COMPUTED
Machine
Language
Routines
for the
Commodore
64
Dozens of easy-to-use routines and programs
which make your Commodore 64 even more
powerful and versatile. Includes programming
aids, game enhancements, and high-speed
graphics utilities.
A COMPUTE! Books Publication
$14.95
□
□
□
□
□
D
□
COMPUTERS
Machine
Language
Routines
for the
Commodore
64
COMPUTE! Publicationsjnc©
One of the ABC Publishing Companies
Greensboro, North Carolina
Commodore 64 is a trademark of Commodore Electronics Limited.
The following articles were originally published in COMPUTE! magazine, copyright 1983,
COMPUTE! Publications, Inc.: "64 Escape Key" (August — originally titled "VIC and 64
Escape Key"); "Ultrasort" (September — originally titled "Ultrasort for Commodore");
"Variable Lister" (November).
The following article was originally published in COMPUTE! magazine, copyright 1984,
COMPUTE! Publications, Inc.: "Dr. Video 64" (February).
The following articles were originally published in COMPUTERS Gazette, copyright 1983,
COMPUTE! Publications, Inc.: "The Four-Speed Brake" (August); "RAMtest" (August —
originally titled "Machine Language for Beginners: The Easy Way"); "Disassembling"
(September — originally titled "Machine Language for Beginners: Disassembling"); "64
Searcher" (September); "64 Paddle Reader" (October — originally titled "Improved Paddle
Reader Routine"); "Windows and Pages" (October — originally titled "Machine Language for
Beginners: Windows and Pages"); "Disk Defaulter" (November — originally titled "VIC/64
Disk Defaulter"); "One-Touch Commands" (November — originally titled "One-Touch
Commands for the 64"); "The Assembler" (November — originally titled "Machine Language
for Beginners: The Assembler"); "Foolproof INPUT " (December — originally titled "Foolproof
INPUT for VIC and 64").
The following articles were originally published in COMPUTEI's Gazette, copyright 1984,
COMPUTE! Publications, Inc.: "Auto Line Numbering" (February); "ASCII/POKE Printer"
(March — originally titled "ASCII/POKE Printer for VIC and 64"); "Numeric Keypad" (April);
"Step Lister" (May); "Scroll 64" (June); "Ultrafont + " (July); "Sprite Magic" (August); "String
Search" (August).
The following article was originally published in COMPUTEI's First Book of Commodore 64
Games, copyright 1983, COMPUTE! Publications, Inc.: "Maze Generator."
The following program was originally published in Creating Arcade Games on the Commodore
64, copyright 1984, COMPUTE! Publications, Inc.: "Two-Sprite Joystick."
Copyright 1984, COMPUTE! Publications, Inc. All rights reserved.
Reproduction or translation of any part of this work beyond that permitted by Sections 107
and 108 of the United States Copyright Act without the permission of the copyright owner
is unlawful.
Printed in the United States of America
ISBN 0-942386-48-5
COMPUTE! Publications, Inc. , Post Office Box 5406, Greensboro, NC 27403 (919) 275-9809,
is one of the ABC Publishing Companies and is not associated with any manufacturer of
personal computers. Commodore 64 is a trademark of Commodore Electronics Limited.
ii
Contents
Foreword vii
Chapter 1: Introduction 1
Another Toolbox
Gregg Peele 3
The Assembler
Richard Mansfield 6
Disassembling
Richard Mansfield 14
Windows and Pages
Richard Mansfield 21
Stealing Characters from ROM
J.R. Chaffer 26
Chapter 2: Programming Aids 43
BASIC Aid
Brent Anderson and Sheldon Leemon 45
Auto Line Numbering
Jeff Young 69
Numeric Keypad
Charles Kluepfel 71
One-Touch Commands
David W. Martin 74
Dr. Video
David W. Martin 78
Step Lister
E.A. Cottrell 80
Foolproof INPUT
Charles Brannon 83
64 Searcher
John Krause and David W. Martin 87
The Four-Speed Brake
Dan Carmichael 89
ASCII/POKE Printer
ToddHeimarck 91
64 Escape Key
Thomas Henry 97
Variable Lister
E.A. Cottrell 102
Disk Defaulter
Eric Brandon 106
Chapter 3: High-Speed Graphics 109
Ultrafont + Character Editor
Charles Brannon Ill
Sprite Magic: An All-Machine-Language Sprite Editor
Charles Brannon 131
The Graphics Package
Chris Metcalf 150
Chapter 4: Game Programming 165
Two-Sprite Joystick
Gregg Peele 167
Scroll 64
Peter Mar cotty 171
64 Paddle Reader
Dan Carmichael and Tom R. Halfhill 176
Maze Generator
Charles Bond (Translated to machine language by
Gary E. Marsa and for the 64 by Gregg Peele) 1 78
Multiple-Key Scanner
Chris Metcalf 186
Chapter 5: Applications and Utilities 189
String Search
Glen Colbert 191
Ultrasort
John W. Ross 196
64 Freeze
Dan Carmichael 202
64 Merge
Harold D. Vanderpool 204
RAMtest
Richard Mansfield 209
iv
H
n
H
Appendices 213
I—, A: A Beginner's Guide to Typing In Programs 215
I ' B: How to Type In Programs 217
C: The Automatic Proofreader
Charles Brannon 219
' > D: Using the Machine Language Editor: MLX
Charles Brannon 223
E: The 6502 Instruction Set 230
F: Number Tables 246
Index 253
H
n
n
H
□
□
□
□
□
D
□
Foreword
Machine language. If you're a BASIC programmer, these words may
seem mysterious. Perhaps intimidating. After all, the best programs
— from word processors to arcade games — are written in it. But why
is machine language so special?
Your Commodore 64 doesn't really speak in BASIC. You may be
well versed in that programming language, but your computer isn't.
It has to look up everything you type in and translate it into the
language it does understand — machine language (ML).
ML is simply a series of O's and l's. Bits off or on. When you type
something into the computer — LET A = 2 + 2, for example — the
computer has to use its internal dictionary to look up what that means
in numbers. Then it has to return the answer to you in a way you
can understand.
This constant referring and translating, called BASIC, is just not
as fast as machine language. If you could somehow speak to your 64
in its native tongue, ML, you would be able to execute commands and
programs a hundred, even a thousand, times faster.
Fortunately, you don't have to know how to write machine
language programs to use them. BASIC and ML can work together. The
routines and programs in this book can be added to your own
BASIC programs. All you have to do is type them in.
There are several routines which make it easier to write your own
BASIC programs, from automatically adding line numbers to slow-
ing down listings on the screen. "BASIC Aid," an all machine language
program, gives you 20 tools that simplify BASIC programming.
Graphics utilities let you create custom characters, sprites, or impres-
sive designs, all at machine language speed. If you enjoy writing
games, you'll find the ML joystick, paddle, and keyboard routines
helpful. You can insert other routines to make your screen scroll
horizontally or vertically, or use the maze generator to create random
mazes almost instantly. Other applications let you freeze the display,
sort thousands of things quickly, merge files, search for strings, and
even test your computer's RAM chip.
You don't need to know how or why machine language works
to use these utilities. As long as you know BASIC, you'll be able to
speed up, simplify, and amplify your own programs with the routines
in this book. What once took minutes can take only seconds with
ML. You'll be amazed at how powerful your programs can become.
vii
□
□
□
□
□
D
□
■
|| Chapter 1
■ Introduction
■
I
1
■
■
□
□
□
□
□
D
□
Gregg Peek
Another Toolbox
Machine language is fast Computers are fast. I'm sure
and powerful This simple you've heard that before.
introduction helps you under- The processor inside your
stand what machine language Commodore 64, called the
can and should do. There's «5 J0 chip takes only one
even a short routine which ^° n ^Z°rnr^L
±, ^ ^ fa acts' microsecond) to complete
compares the speeds of BASIC Qne wQrk ^ The CQm .
and machine language. puter can process over one
hundred thousand instructions in one second. Speedy.
Unfortunately, the 64 is only that quick when it's executing
instructions written in its native tongue, machine language (ML).
Machine language is essentially a series of numbers stored in the
computer's memory. Remembering those numbers, and what they
do, is sometimes hard for humans. That's why most of us use a dif-
ferent language to speak to the computer. Called BASIC, it's much
slower because it has to translate what you enter into code that
the computer can understand. There's nothing inherently wrong
with this; if you didn't have BASIC to use, you would have to talk
to the 64 in machine language. BASIC may be easier for the novice
programmer to remember, but it is slower.
Quick Clear
To see the difference in speed between BASIC and ML, let's look at
two programs, both of which do the same thing. The high-resolution
screen on the Commodore 64 contains 8000 bytes of information.
Clearing that screen with a BASIC program takes at least 30 seconds.
Here's what the BASIC version would look like:
5 PRINT" {CLR} "
10 POKE 53272, PEEK( 53272 )0R8
, 20 POKE 53265, PEEK( 53265 )0R32
30 FOR T=8192 TO 8192+8000: POKE T,0:NEXT
40 GET A$:IF A$="" THEN 40: REM HIT SPACE TO CONTI
NUE
50 POKE 53265, PEEK( 53265 )AND223
60 POKE 53272,21
Type it in and RUN it. It does the job, but it's slow. Using machine
language, however, clears the screen almost instantly. Type in the
following program, RUN it, then enter SYS 49152 to see the quickness
of ML.
3
1 : Introduction
10 1=49152 :IFPEEK( 49152 )=169THENSYS49152: END
20 READ A: IF A=256 THEN SYS49152:END
30 POKE I, A: 1=1+1: GOTO 20
49152 DATA 169,147,32,210,255,173,24
49159 DATA 208,9,8,141,24,208,173
49166 DATA 17,208,9,32,141,17,208
49173 DATA 169,0,168,133,252,169,32
49180 DATA 133,253,169,0,145,252,200
49187 DATA 208,249,230,253,165,253,201
49194 DATA 64,144,241,165,197,201,60
49201 DATA 208,250,173,17,208,41,223
49208 DATA 141,17,208,169,21,141,24
49215 DATA 208,96,256
Speed is often essential to a program. Arcade games which need
fast action and smooth animation use ML to add realism to move-
ment and to provide precise player control. Most professional word
processors are written in machine language, since moving text in
BASIC is especially slow. And many short routines, such as the ones
in this book, use ML's speed to enhance particular aspects of
programs written in BASIC.
Finding the Right Mix
Even though machine language is fast, it's sometimes more appro-
priate to use another language. Programs which include complex
formulas, or which don't need ML's speed, can sometimes best
be written in BASIC. Such programs may involve complex bit-
manipulation techniques that are easier or faster to write in BASIC
than in machine language. In fact, it's often most efficient to combine
the features of BASIC and ML. You can use BASIC for sections where
speed is not vital, and ML for parts which require quick execution.
Using the SYS command, you can call these machine language
routines when they're needed. For instance, the high-resolution
screen-clearing routine might be used to accompany a BASIC
graphics program.
Since the operating system of your 64 is written in machine
language, there are several routines already included in the BASIC
ROM that you can use for your own programs. Some of these routines
print to the screen or other device, move the cursor to any place on
the screen, or save/load to disk or tape. Many programmers use these
routines as part of their programs, saving them considerable time and
effort. Several of the programs in this book do just that.
Being able to mix BASIC and ML has other advantages. A machine
language program can add new features and commands to BASIC.
4
Introduction: 1
These additions can speed up programming in BASIC by providing
high-speed line renumbering, search and replace functions, and other
helpful utilities. Take a look at the "Programming Aids" section for
some good examples of these kinds of routines.
Machine language can also help you create your own ML pro-
grams. To make it easier to write machine language, a series of
mnemonics, each representing a certain operation, helps you keep
track of what you write. A program which reads these mnemonics
and changes them to numbers (which, after all, is what the computer
wants to see) is a special kind of ML program called an assembler.
Assemblers are important tools to ML programmers, since they
allow you to use easy-to-remember symbols instead of hard-to-recall
numbers. A simple assembler is included in this book, but a more com-
plex one can be found in Richard Mansfield's book, The Second
Book of Machine Language. There are also commercially available
assemblers for the 64 on the market.
Tools
This book is not meant to teach you how to write machine language.
There are other books for that. You'll find something different here:
powerful machine language tools. These tools supplement BASIC
with added commands and features, or replace functions of BASIC
with speedier ML versions. Some of the tools are written in machine
language and are meant to be used by themselves. Others are in the
form of a BASIC loader which POKEs machine language data into
memory. Most of these can be easily added to your own BASIC pro-
grams. Whatever the form, you'll find these ML utilities fast, powerful,
and versatile. Just what a tool should be.
Richard Mansfield
The Assembler
One of the basic tools of machine People often use the words
language (ML) programming is machine language and
an assembler. Richard Mansfield, assembly language inter-
senior editor of COMPUTE/ changeably. However,
Publications, offers his assembler machine language is
along with some elementary becomin 8 the more common
explanations and examples on te f m - It>s more accurate ~
how it's used when you program in this
nownsusea. language you > re speaking
directly to. your computer in its native tongue.
Unfortunately, the computer's internal language is almost
impossible for humans to work with. These machines communicate
only with numbers, and very odd numbers at that. They're binary,
consisting of only l's and O's, grouped together in eight-digit clusters
called bytes: 01100111, 11110001, and so on. Humans find it easier to
work with words. That's where an assembler comes in.
The Primary Tool
We first need to build the basic tool for machine language (ML)
programming. Type in the program and you'll have your own
working assembler.
The assembler works like this: You type in a wordlike, three-letter
code, and the assembler looks up the correct number (in the com-
puter's language) and POKEs it into RAM memory to start forming an
ML program. In a minute we'll create a simple ML program to show
you how ML programming is done. But let's clear up a few possible
sources of confusion first.
These wordlike codes are called mnemonics, which means
they've been designed to be simple to remember. It's easy enough to
remember what USA stands for. Likewise, you can quickly pick up
the essential ML words. There are 56 of these commands available to
you, roughly as many words as there are in BASIC. But, like BASIC,
there is a core group of about 20 important ones. They are the only
ones you need to use to get almost anything accomplished. What's
more, the ML words are easy to learn and remember. For example,
BRK stands for BReaK (like BASIC'S STOP), JSR is Jump to Sub-
Routine (GOSUB), and RTS is ReTurn from Subroutine (RETURN). The
command which does the same thing as BASIC'S GOTO is called
JMP, for JuMP.
Introduction: 1
A Kind of Swing
ML programming involves a kind of swing between Command and
Target. First you give a command, then you give the specific target for
that command. Then another command, another target. These
paired-event phenomena are called by many names and appear in
many disguises in programming as well as in real life. They're called
Operator/Operand, Instruction/Argument, Mnemonic/Address,
Analyst/Analysand, Shopper/Apples, Thief/Victim.
Notice that the first half of the pair is the more general, the
second more specific. At a given moment, the apple is the specific
thing the shopper's involved with, but the shopper will be buying
other things during this visit to the store. Similarly, a thief is always
a thief, but a victim is a victim only that once (we hope). Also, the
transaction which all these pairs have in common is that the first half
of the pair is doing something to the second half. Together they
form a complete action in the sense that Open/Envelope or Eat/Peach
are paired (command/target) actions.
A Robot Dinner
If you think about it, you can see this do-it-to-it rhythm throughout
BASIC programming: PEEK (8), PRINT "HELLO", SAVE "PROGRAM",
X = 15, X = X + 1, GOTO 1500, and so on. The reason we're stressing
this distinction, this rhythmic swing between actor and acted-upon,
is because an ML program is constructed in precisely this way — you
make a list of tiny, elementary actions for the computer to later carry
out. It's like a robot dinner: spear/meat, raise/arm, insert/food, chew/
morsel, lower/arm, spear List enough of these mini-instructions
and you can do amazing things.
One result of all this is that an ML program doesn't look like a
BASIC program. BASIC tends to spread these pairs out along a line:
100 Y=3:X=X+l:POKE 63222, Y:Y=PEEK(1200)
ML lists each tiny action-pair on its own line:
100 LDY #3
110 INX
120 STY 63222
130 LDY 1200
These two programs are doing exactly the same thing, but in
different ways. STY and LDY mean STore Y and LoaD Y (it's like a
variable in BASIC). INX means INcrement X (raise it by one). The #
sign means to think of the number as literally the number three, not
1: Introduction
address three. Without the #, the computer assumes you mean a
memory location.
Take a look at the mnemonics here They're all three-letter words.
They are always the first thing on each line. And they usually have
their target right next to them (the INX doesn't because the mnemonic
itself already contains the specific information required). The other
half of the pair, those numbers, is called addressing modes in ML. In
In general, that's because numbers are usually being sent to and from
addresses in the computer's memory while an ML program is running.
That, plus simple arithmetic, is the essence of what a computer does
to accomplish any given task.
We won't get into the addressing modes (there are about ten) right
now, but you can already recognize two of them: Line 100 's mode is
called immediate addressing (the number is immediately after the
instruction, not in some memory location elsewhere in the com-
puter), and line 110 's mode is called implied addressing (because the
instruction contains its own target).
Putting the Assembler to Work
Enough theory, let's do something. Let's assemble a small program.
If you've typed in the program, the first thing to do is to change line
10 so that the assembler will accept ordinary decimal numbers. It's
designed to work with either decimal or hexadecimal, but we've not
yet touched on hex so we'll stick with the familiar. Change the line to:
10 H=0
Then RUN the assembler and type in 830 when it asks you where
you want to put the ML program. That's a safe place until you next
load in a program from cassette. ML can be put into a variety of places
in RAM. BASIC, of course, has a computer-determined starting loca-
tion in memory, but you specify the start of an ML program. Now
you'll see that address printed onscreen. The addresses where the
instructions are being stored will function as the "line numbers" for
your reference when programming. Unlike BASIC, you can't go back
up and change a line If you make a mistake, start over. (There are easier
ways to fix errors, but that, too, is more complicated, so we'll stick
to simpler methods for now.)
Now type LDY #0, hit RETURN, and you've written a line of ML
which will put a zero into the Y register. (You'll see the numbers
forming the ML version of your program appear to the right of the
mnemonic/address you've typed.) Then the assembler will furnish
8
n
Introduction: 1
H
< )
you with the next available "line number" address in RAM, 832. The
mnemonic/address pair LDY #0 uses up two bytes.
You are ready to type in your next pair: LDA #66. Hit RETURN
on this line and you've put the code for the letter B into the A register.
Then type in the rest of our ML program, one pair per line:
JSR 65490
DEY
BNE 834
RTS
That's it. To let the assembler know that you're through with your
program, type END instead of a normal mnemonic and it will tell
you the start and end addresses of your ML program. Then, having
done its job, the assembler quits. The mnemonics and addresses
were all POKEd into their proper places after being translated into the
machine's language. To see what happens when this RUNs, you can
type SYS 830 and see the effect of the small ML loop we wrote. You'll
get 256 B's onscreen in record time. Not something you've been
anxious to do? More useful things are on their way.
In the next few chapters we'll look at some other aspects of
machine language, including a disassembler that you can use to pull
apart ML programs. You'll see how a simple ML program is created
and then find valuable utilities that will allow you to use the speed
and power of machine language in your own programs.
You're on your way to using machine language.
The Assembler
Formis take-proof program entry, be sure to read "The Automatic Proofreader, ' ' Appendix C.
10 H=l : REM IP H = THEN ASSEMBLY IS IN DECIMAL
:rem 42
50 HE$="0123456789ABCDEF":SZ=1:ZO$="000" : rem 166
100 PRINT" {3 SPACES} SIMPLE {3 SPACES } ASSEMBLER
{2 SPACES } CONVENTIONS : " :rem 90
^ 110 DIMM$(56),TY(56),0P(56) :rem 181
f I 120 F0RI=1T056:READM$(I) :rem 160
122 ROP$=MID$(M$(I),4,l) :TY( I)=VAL(ROP$) :rem 5
124 0P$=RIGHT$(M$(I),3) :OP(I)=VAL(OP$) :rem 155
126 M$(I)=LEFT$(M$(I),3) : rem 235
140 NEXTI: PRINT :rem 228
150 PRINT "IMMEDIATE { 5 SPACESjLDA #15 : rem 46
155 PRINT "ABSOLUTE {6 SPACESjLDA 1500 :rem 64
160 PRINT "ZERO PAGE {5 SPACESjLDA 15 : rem 218
165 PRINT "ACCUMULATOR {3 SPACES }ASL :rem 107
170 PRINT "INDIRECT X{4 SPACES } LDA (15X) :rem 209
175 PRINT "INDIRECT Y{4 SPACESjLDA (15)Y :rem 216
n
H
n
1: Introduction
177 PRINT"ZERO PAGE X{3 SPACESjLDA 15X :rem 146
179 PRINT"ZERO PAGE Y{3 SPACESjLDX 15Y :rem 173
180 PRINT "ABSOLUTE X{4 SPACESjLDA 1500X : rem 238
185 PRINT "ABSOLUTE Y{4 SPACESjLDA 1500Y :rem 245
189 PRINT: PRINT "{4 SPACES } ENTER ALL NUMBERS IN " ;
:rem 127
190 IFH=1 THENPRINT"HEX":GOTO200 : rem 201
195 PRINT "DECIMAL" : rem 95
200 PRINT: PRINT "INPUT STARTING ADDRESS FOR ML PROG
RAM:": INPUTS A$ : rem 128
210 IFH=1THENH$=SA$ :GOSUB5000:SA=DE:GOTO220
:rem 130
215 SA=VAL(SA$) : rem 85
220 TA=SA : PRINT " { CLR } " : REM CLEAR THE SCREEN
:rem 190
230 IFH=1THENDE=SA:SZ=3:GOSUB4000:PRINTH$; :GOTO240
:rem 175
235 PRINTSA" " ; :rem 58
240 INPUTMN? :PRINT" {UP} "SPC(20) ; :REM GO UP ONE LIN
E AND OVER 20 SPACES : rem 232
241 REM ADD NEW PSEUDO-OPS HERE : rem 65
242 IFRIGHT$(MN$,7)="FORWARD"THENFB=SA : rem 90
243 I FRIGHT $ ( MN$ , 7 )=" RESOLVE "THENFR=SA-FB : POKEFB+1
,FR-2:PRINT"{2 SPACES } OK" :GOTO230 : rem 72
244 IFRIGHT$(MN$,4)="POKE"THEN246 :rem 182
245 GOTO 250 :rem 107
246 PRINT "ADDR, NUMBER ( DEC ) " ; : INPUTADR, NUM: POKEADR,
NUM:GOTO230 : rem 246
250 IFMN$="END"THENPRINT: PRINT" {6 SPACES } PROGRAM I
S FROM "TA "TO " SA : END : rem 13
260 L=LEN(MN$) :L$=LEFT$ (MN$ , 3 ) : rem 181
270 FORI=1TO56:IFL$=M$(I)THEN300 : rem 136
280 NEXTI :rem 34
290 GOTO850 :rem 113
300 REM PRIMARY OPCODE CATEGORIES : rem 59
301 TY=TY( I ) : OP=OP ( I ) :rem 20
305 IFFB=SATHENTN=0:GOTO2010 : rem 244
310 IFTY=0THENGOTO1000 : rem 102
320 IFTY=3THENTY=1 :IFL=3THENOP=OP+8 :GOTO1000
: rem 81
330 R$=RIGHT$(MN$,L-4) :IFH=1THENGOSUB6000 :rem 200
340 LR$=LEFT$(R$,1) :LL=LEN(R$) :IFLR$="#"THEN480
:rem 184
350 IFLR$="("THEN520 : rem 88
360 I FTY=8THEN6 00 : rem 15
370 IFTY=3THENOP=OP+8:GOTO1000 : rem 135
380 IFRIGHT$ ( R$ , 1 )="X"ORRIGHT$ ( R$ , 1 )="Y"THEN630
:rem 210
390 IFLEFT$(L$,1)="J"THEN820 : rem 44
10
Introduction: 1
400
TN=VAL ( R$ ) :IFTN>255THEN430
:rem 40
410
IFTY=10RTY=30RTY=40RTY=5THENOP=
•OP+4 :rem 133
420
GOTO2000
: rem 145
430
H%=TN/ 256 : L%=TN-2 5 6* H% : I FTY=20RTY=7THENOP=OP+8
:GOTO470
:rem 92
440
IFTY= 1 ORTY= 3 ORT Y=40RTY=5 THENOP=
<OP+12:GOTO470
:rem 197
450
IFTY=6ORTY=9THEN470
:rem 214
460
GOTO850
:rem 112
470
GOTO3000
:rem 151
480
TN=VAL ( RIGHT$ ( R$ , LL-1 ) )
:rem 58
490
IFTY=1 THENOP=OP+8 : GOTO2000
:rem 137
500
IFTY=40RT Y=5 THENGOTO 2000
:rem 44
510
GOTO850
:rem 108
520
IFRIGHT$ ( R$ , 2 )=" ) Y"THEN540
:rem 184
530
IFRIGHT? ( R$ , 2 )="X) "THEN570
:rem 187
540
TN=VAL(MID$(R$,2,LL-3) )
:rem 243
550
IFTY=lTHENOP=OP+16 :GOTO2000
:rem 181
560
GOTO850
:rem 113
570
TN=VAL(MID$(R$,2,LL-3) )
:rem 246
580
IFTY=1THENGOTO2000
:rem 113
590
GOTO850
:rem 116
600
TN=VAL ( R$ ) : TN=TN- SA-2:IFTN<-1 2 80RTN > 1 2 7 THENP RI
NT "TOO FAR ";:GOTO850
:rem 154
610
I FTN < 0THENTN=TN+2 5 6
:rem 172
620
GOTO2000
:rem 147
630
IFRIGHT$(R$,2)=" )Y"THEN540
: rem 186
640
IFRIGHT$(R$,1)="X"THEN720
:rem 144
650
REM *ZERO Y
:rem 66
660
TN=VAL( LEFT? (R$, LL-1 ) ) : IFTN>255THEN680: rem 249
670
I FT Y= 2 ORT Y=5 THEN 7 3
:rem 209
675
I FTY=1 THEN7 60
:rem 24
680
GOSUB770:IFTY=1THENOP=OP+24:GOTO710 :rem 230
690
IFTY=5THENOP=OP+28 :GOTO710
:rem 151
700
GOTO850
:rem 109
710
GOTO3000
:rem 148
720
TN=VAL ( LEFT $(R$, LL-1) ) :IFTN>255THENGOSUB770 :GO
TO780
:rem 136
730
IFTY=2THENOP=OP+16 :GOTO760
: rem 145
740
IFTY=lORTY=3ORTY=5THENOP=OP+20 :
GOTO760 :rem 10
750
GOTO850
: rem 114
760
GOTO2000
: rem 152
770
H%=TN/256 :L%=TN-256*H% : RETURN
:rem 187
780
IFTY=2THENOP=OP+24 :GOTO810
:rem 145
790
IFTY=10RTY=30RTY=5THENOP=OP+28 :GOTO810 :rem 19
800
GOTO850
:rem 110
810
GOTO3000
:rem 149
820
TN=VAL(R$)
:rem 35
830
GOSUB770
:rem 185
11
1 : Introduction
840 GOTO710 srem 109
850 PRINT "{RVS} ERROR ":GOTO230 :rem 18
1000 REM 1 BYTE INSTRUCTIONS srem 191
1010 POKESA,OPsSA=SA+lsIFH=lTHEN 1030 :rem 189
1020 PRINTOP:GOTO230 :rem 247
1030 DE = OP:GOSUB4000:PRINTH$:GOTO230 :rem 226
2000 REM 2 BYTE INSTRUCTIONS : rem 193
2005 IFTN>255THENPRINT" INCORRECT ARGUMENT. (#5 IN
HEX IS #05)":GOTO230 : rem 93
2010 POKESA,OPsPOKESA+l,TNsSA=SA+2 : IFH=1THEN2030
:rem 231
2020 PRINTOP;TN:GOTO230 :rem 213
2030 DE » OPsGOSUB4000sPRINTH$" "; :rem 90
2040 DE = TNsGOSUB4000sPRINTH$sGOTO230 : rem 231
3000 REM 3 BYTE INSTRUCTIONS : rem 195
3010 POKESA, OP : POKESA+1 , L% : POKESA+2 , H% : SA=SA+3 : IPH
=1THEN3030 :rem 172
3020 PRINTOP;L%;H%:GOTO230 :rem 77
3030 DE = OP:GOSUB4000:PRINTH$" "; :rem 91
3040 DE = L%:GOSUB4000:PRINTH$" "; : rem 46
3050 DE = H%:GOSUB4000:PRINTH$:GOTO230 :rem 180
4000 REM{2 SPACES} DECIMAL TO HEX (DE TO H$) : rem 8
4010 H$="":FORM=SZTO0STEP-l:N%=DE/(16tM) sDE=DE-N%*
16tM:H$=H$+MID$(HE$,N%+l,l) srem 179
4020 NEXT : SZ=1 : RETURN :rem 116
5000 REM{ 2 SPACES }HEX TO DECIMAL (H$ TO DE) srem 9
5010 D=0 : Q=3 s F0RM=1T04 : FORW=0TO15 s IFMID$ (H$,M, 1 )=M
ID$(HE$,W+1,1)THEN5030 srem 221
5020 NEXTW srem 93
5030 Dl=W*(16t(Q) ) $D=D+DlsQ=Q-lsNEXTMsDE=INT(D) sRE
TURN srem 41
6000 REM ACCEPT HEX OPCODE INPUT AND TRANSLATE IT
{ SPACE }TO DECIMAL srem 57
6010 IFLEFT$(R$,1)="#"THENH$="00"+RIGHT$(R$,2) sGOS
UB5000sR$="#"+STR$(DE) s RETURN srem 234
6020 LS=LEN(R$) sAZ$=LEFT$ ( R$ , 1 ) sZA$=MID$ ( R$ ,LS, 1 ) s
IFAZ$o"("THEN6050 srem 126
6030 IFZA$="Y"THENH$="00" +MID$ ( R$ , 2 , 2 ) SGOSUB5000 sR
$=" ( "+STR$ ( DE) +" ) Y" s RETURN srem 30
6040 IFZA$=") "THENH$="00"+MID$(R$,2,2) sGOSUB5000sR
$=" ( "+STR$(DE)+"X) " sRETURN srem 238
6050 IFZA$="X"ORZA$="Y , *THEN6070 srem 40
6060 H$=LEFT$ ( ZA$ , 4-LS ) +R$ s GOSUB5000 s R$=STR$ ( DE ) s R
ETURN srem 30
6070 IFLS=5THENH$=LEFT$(R$,4) SGOTO6090 srem 253
6080 H$="00"+LEFT$(R$,2) srem 186
6090 GOSUB5000sR$=STR$(DE)+ZA$s RETURN srem 252
20000 DATAADC1097 ,AND1033 ,ASL3002 ,BCC8144,BCS8176 ,
BEQ8240,BIT7036,BMI8048 srem 96
12
Introduction: 1
20010 DATABNE8208,BPL8016,BRK0000,BVC8080,BVS8112,
CLC0024,CLD0216,CLI0088 :rem 114
20020 DATACLV0184 ,CMP1193 ,CPX4224 ,CPY4192 , DEC2198,
DEX0202,DEY0136,EOR1065 : rem 184
20030 DATAINC2230 , INX0232 , INY0200 , JMP6076 , JSR9032 ,
LDA1161,LDX5162,LDY5160 : rem 200
20040 DATALSR3066 , NOP02 34 , ORA1001 , PHA007 2 , PHP0008 ,
PLA0104,PLP0040,ROL3034 : rem 185
20050 DATAROR3098,RTI0064,RTS0096,SBC1225,SEC0056,
SED0248,SEI0120,STA1129 :rem 216
20060 DATASTX2134,STY2132,TAX0170,TAY0168,TSX0186,
TXA0138,TXS0154,TYA0152 :rem 79
Richard Mansfield
U
u
Disassembling
Knowing how to assemble A disassembler is the second
machine language (ML) pro- of two major tools you'll M
grams isn 't enough; you also be using when you work
need to know how to convert the with machine language. In
numbers the computer uses into order to understand what i j
thingsyoucan understand. A it does, we'll need to briefly ^
disassembler does this. fT W £
„ . ^ , ^ tool, an assembler, which
7#e stmple-to-use dtsas- . ., . . V
' ,7' , , was described in the pre-
sembler included here makes vious section
ML programs less confusing A n assembler is used to
and easier to study. wr ite an ML (machine lan-
guage) program in the same way that BASIC is used to write a BASIC
program. An assembler lets you type in ML instructions like LDA #8
and then translates the instructions into numbers and POKEs them into
memory for you. Take a look at Program 3 • The first line, numbered
884, says LDA (LoaD the Accumulator) with the number eight. This
same instruction appears in different form in line 882 of Program 2:
DATA 169,8. An assembler would translate your LDA instruction into
the number 169 . If you're just starting out with ML, these instructions
won't mean much to you yet, but for now all we want to do is get a
feel for the broad concepts of ML.
To look at "assembling" another way, it helps to realize that
there's a similar process going on when you write a BASIC program.
After you type in a BASIC command, the BASIC interpreter translates
it into a token, a single-byte representation of the command, and
stores the token in memory. So, a line of BASIC is stored inside the
computer in a different form than you would see on the screen
when you type it in. The word LIST would be stored in four bytes,
but the command LIST would be crunched down by BASIC into
only one byte. Similarly, an assembler takes your LDA and turns it
into the number 169, which can be stored in a single byte. These \ 1
words — LDA and LIST — are for our convenience. They are easier ' — '
for us to work with. The computer only needs numbers and so
BASIC and its ML equivalent, an assembler, accepts the words, but \ " 1
stores numbers. — '
An Understandable Version —
Of course, you need to go the opposite way sometimes, from LJ
the numbers back to the words. If the computer stores, interprets,
and executes programs as pure numbers, how can we examine or ^ -
14
□
Introduction: 1
modify a program? We don't want to study a list of numbers, how-
ever efficient they are for the computer's internal use. Program 2 is
a good example of this. Program 1, a disassembler, does for ML
what the LIST command does for BASIC programs. It takes a look
at a compressed, numeric, machine-readable program in memory
and prints out an understandable, human-readable version.
Let's look at an example. A fragment of a program which puts
every possible number (0-255) into every memory cell in your
computer's RAM memory appears in Programs 2 and 3 here. Type
in and SAVE Program 1, then type in and RUN Program 2. Next,
LOAD Program 1 again, and when the disassembler asks you for
START ADDRESS, type 884. That's the address where the fragment
starts in RAM memory. You'll then see your screen fill with the
disassembly of the ML fragment. It should look something like
Program 3.
At this point, you will probably find it difficult to understand
this disassembly listing. As you begin to learn the meaning of ML
instructions, however, the purpose of this fragment will become
clear. As a quick explanation: Line 898 copies a number from the
accumulator into a cell in RAM memory. Then line 900 compares
the RAM memory cell against the accumulator. If they are the same
(BEQ means Branch if EQual), we are sent down to lines 925 and 926,
where the number in the accumulator is raised by one. We go back
and test the same cell over and over, raising the number each time
so we can see if that cell will hold all the possible numbers.
Just the way that IF-THEN tests in BASIC, if we had a bad
memory cell and the number was found to be not equal in line 900,
we would "fall through" the BEQ to line 904, which would print
out an error message on the screen to alert us about the bad memory.
By the way, we've been calling the numbers on the left side of Pro-
gram 3 "line numbers." In fact, they're memory addresses where the
instructions were found in RAM. It's useful, though, to think of them
as similar to BASIC'S line numbers. They serve the same purpose.
Don't be concerned if this is difficult to follow. We're jumping
into ML to get our feet wet. It's likely that you learned BASIC the
way I did: by working with the language and making lots of mistakes
and not fully understanding what was going on at first. So we'll
plunge into ML by starting off with the main tools, the assembler
and the disassembler. You won't be able to use them with very
much skill to begin with, but just working with them is probably
the fastest way to learn.
15
1 : Introduction
Trying It Out
We can conclude with a few comments about the disassembler.
There are several graphics features of this disassembler which can
make it easier to visualize the programs it disassembles. All branch-
ing instructions (like BEQ), JSRs, andJMPs (the equivalents of GOSUB
and GOTO) are offset on the screen to indicate that the flow of the
program might be taking a new course at that point. Likewise, the
RTS instruction (ReTurn from Subroutine, the equivalent of BASIC'S
RETURN) causes a line to be drawn, marking the end of a subroutine.
Line 210 of Program 1 PEEKs the ML command from memory.
If it cannot make a match against the array containing all legal ML
instructions (lines 820-960), a ? is printed on screen in line 230.
When you see a series of question marks during a disassembly, it
means that you are not disassembling an ML program, but rather have
come across a "data table." This would be a list of numbers or words
which might be used by an ML program, but is not actually ML code .
You can use the disassembler to look into the heart of your
BASIC language. Just give an address between 40960-49151 as the
START ADDRESS, and you can see the insides of one of the most
complex ML programs ever written: your BASIC. The next article
will show you how to go directly into BASIC and access some of
its ML subroutines.
Program 1. A Disassembler
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
100 HE$="0123456789ABCDEF" : rem 101
110 L$=" ":J
$="{4 SPACES } >" :rem 76
120 PRINT"{2 SPACES}DISASSEMBLER":PRINT:DIMM$(15,1
5) :rem 119
130 FORI=0TO15:FORB=0TO14:READM$(I,B) : NEXTB : NEXT I
: rem 94
140 REM START MAIN LOOP : rem 102
150 PRINT "STARTING ADDRESS (DECIMAL) " ; ;INPUTSA:TA=
SA :rem 82
160 PRINT "START ADDRESS HEX{2 SPACES }";: DE=SA: ZX= 3
:GOSUB970:PRINTH$"{2 SPACES}" : rem 221
170 IFSA<0THENEND : rem 45
180 I=SA :rem 179
190 REM PRINT ADDRESS : rem 17
200 PRINTI" "; :rem 231
210 X=PEEK(I) :rem 231
220 GOSUB1040 :rem 217
230 IFL%=15ORM$(H% / L%)="0"THENPRINT" ?{5 SPACES}"X
:CK=0:LN=LN+1:GOTO260 :rem 52
16
I i
n
n
Introduction: 1
H
f I
n
n
n
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
420
430
440
450
460
470
480
490
500
510
520
530
540
550
560
570
580
590
600
610
620
630
640
650
660
670
680
PRINTM$(H%,L%) ;
GOSUB1070 : IFEQTHENEQ=0
1=1+1
IFLN=20THENLN=0 : GOTO1000
GOTO 190
IFCK=12THEN320
: rem 42
:rem 112
:rem 195
:rem 203
:rem 109
: rem 28
B=PEEK( 1+1) :IFB>127THENB=( (NOTB )AND255 ) +1 :B=-B
:rem 134
BAD=I+2+B: PRINT" { 8 SPACES } "BAD : 1=1+1 : RETURN
:rem 252
IFH%>8THEN730 : rem 208
IFH%=2THENPRINT" {6 SPACES}"; :J=1:GOTO750
:rem 61
IFH%=6THENPRINT:PRINTL$:EQ=1 : RETURN : rem 81
IFH%=6THENRETURN : rem 22
PRINT :rem 38
RETURN :rem 122
IFCK=12THEN410 : rem 28
PRINT" ("PEEK(I+1)"),Y" : rem 162
1=1+1: RETURN : rem 217
PRINT" ("PEEK(I+1)",X)" :rem 154
1=1+1: RETURN :rem 219
IFCK=12THEN460 : rem 29
PRINT" "PEEK(I+1)",X" :rem 76
1=1+1: RETURN : rem 222
PRINT" { 2 SPACES }" PEEK (1+1) : rem 134
1=1+1: RETURN : rem 224
IFCK=12THEN510 : rem 30
PRINT" "PEEK(I+1) ",X" : rem 81
1=1+1: RETURN : rem 218
PRINT"{2 SPACES }" PEEK (1+1) : rem 130
1=1+1: RETURN : rem 220
IFCK=12THEN510 : rem 26
IFH%=90RH%=11THENPRINT" "PEEK( 1+1) ",Y":rem 156
IFH%=7ORH%=15ORH%=5ORH%=3THEN480 : rem 132
IFH%=13THEN440 : rem 255
PRINT:GOTO500 : rem 49
PRINT: RETURN : rem 68
IFCK=12THEN730 : rem 36
I$="Y" :GOTO750 :rem 236
IFCK=12THEN630 : rem 28
I$="X":GOTO750 :rem 237
IFH%=6THENPRINT" {6 SPACES}"; : I$="Z" :GOTO750
:rem 212
IFH%=2THEN750 : rem 208
IFH%=4THENPRINTJ$; :GOTO750 : rem 124
IFH%=8ORH%=10ORH%=12ORH%=14THEN750 : rem 226
GOTO380 :rem 113
IFCK=12THEN750 : rem 38
17
1 : Introduction
690 I$="X":GOTO750 : rem 244
700 IPCK=12THEN750 srem 31
710 IFH%=11THENI$="Y" :GOTO750 : rem 184
720 I$="X":GOTO750 :rem 238
730 PRINT" {3 SPACES } # " PEEK ( 1+1 ) : rem 169
740 1=1+1: RETURN :rem 224
750 N=PEEK(I+l)+PEEK(I+2)*256 : rem 80
760 IPI$=""THEN800 :rem 225
770 IFI$="X"THENPRINT"{2 SPACES } "N" , X" : rem 137
780 IFI$="Y"THENPRINT"{2 SPACES] "N",Y" : rem 140
785 IFI$="Z"THENPRINT" ("N") H :rem 94
790 1$="" : 1=1+2: RETURN : rem 14
800 PRINT" {2 SPACES} "N: 1=1+2 : rem 29
810 RETURN srem 121
820 DATABRK,ORA,0,0,0,ORA,ASL,0,PHP,ORA,ASL,0,0,OR
A,ASL,BPL,ORA,0,0,0,ORA,ASL : rem 113
830 DATA0,CLC,ORA,0,0,0,ORA,ASL,JSR,AND,0,0,BIT,AN
D,ROL,0,PLP,AND,ROL,0,BIT : rem 7
840 DATAAND, ROL,BMI, AND, 0,0,0, AND, ROL f 0, SEC, AND, 0,
0, 0, AND, ROL,RTI,EOR, 0,0,0 : rem 160
850 DATAEOR, LSR, , PHA, EOR, LSR, , JMP, EOR, LSR, BVC, EO
R,0,0,0,EOR,LSR,0,CLI,EOR, : rem 18
860 DATA0 , , EOR, LSR, RTS , ADC ,0,0, , ADC , ROR, , PLA, AD
C :rem 12
870 DATAROR, 0, JMP, ADC, ROR, BVS, ADC, 0,0,0 :rem 77
880 DATAADC , ROR, , SEI ,ADC, ,0,0 , ADC, ROR, , STA
:rem 149
890 DATA0,0,STY,STA,STX,0,DEY,0,TXA,0,STY,STA
: rem 45
900 DATASTX , BCC , STA, , , STY, STA, STX , , TYA, STA, TXS ,
0,0,STA,0,LDY,LDA,LDX,0 : rem 60
910 DATALDY , LDA , LDX , , T AY , LD A , T AX , , LDY , LD A , LDX , BC
S,LDA,0,0,LDY,LDA,LDX,0 : rem 247
920 DATACLV , LDA , T SX , :rem 30
930 DATALDY, LDA, LDX , CPY , CMP , , , CPY , CMP , DEC , , I NY ,
CMP,DEX,0,CPY,CMP,DEC : rem 177
940 DATABNE, CMP, 0,0,0, CMP, DEC, 0,CLD, CMP, 0,0,0, CMP,
DEC,CPX,SBC,0,0,CPX,SBC,INC : rem 35
950 DATA0, INX, SBC, NOP, 0,CPX, SBC, INC, BEQ, SBC, 0,0,0,
SBC, INC, 0,SED, SBC, 0,0,0, SBC : rem 67
960 DATAINC : rem 147
970 REM MAKE DECIMAL INTO HEX : rem 176
980 H$="":FORM=ZXTO0STEP-l:N%=DE/(16tM) :DE=DE-N%*1
6tM:H$=H$+MID$(HE$,N%+l,l) :rem 148
990 NEXT: RETURN : rem 251
1000 PRINT "TYPE C TO CONTINUE FROM" I :rem 156
1010 GETK$:IFK$=""THEN1010 :rem 187
1020 IFK$="C"THENSA=I:TA=SA:GOTO170 :rem 121
1030 INPUTSA:TA=SA:GOT017^ :rem 147
18
Introduction: 1
1040 REM ANALYZE H & L OF OPCODE. : rem 198
1050 H%=X/16:L%=X-H%*16 :rem 201
1060 : RETURN : rem 225
1070 REM FIND ADDRESS TYPE & GOSUB : rem 187
1080 CK=H%/2sIFCK=INT(CK)THENCK=12 : rem 29
1090 L%=L%+1 :rem 69
1100 ONL%GOSUB290, 380, 730, 1130, 480, 480, 530, 1130, 58
0,590,580,1130,610,680,700 : rem 75
1110 CK=0 :rem 190
1120 LN=LN+1 :rem 145
1130 RETURN :rem 165
Program 2. Fragment
For mistake-proof program entry, be sure to read "The Automatic Proofreader,' 'Appendix C.
800 FOR ADRES=884 TO 930: READ DATTA : POKE AD RES , DAT
TA : NEXT ADRES :rem 44
882 DATA 169,8,133,58 :rem 28
888 DATA 169,0,133,57,160,0 :rem 56
894 DATA 24,141,0,4,145,57 :rem 1
900 DATA 209,57,240,21,152,72 :rem 144
906 DATA 165,58,72,32,179,3 :rem 64
912 DATA 104,133,58,104,168,169 :rem 255
918 DATA 0,230,57,208,7,230 :rem 47
924 DATA 58,24,105,1,208,221,96 :rem 249
Program 3. Fragment Disassembly
884
LDA
# 8
886
STA
58
888
LDA
#
890
STA
57
892
LDY
#
894
CLC
895
STA
1024
898
STA
(
57 )
900
CMP
(
57 )
902
BEQ
925
904
TYA
905
PHA
906
LDA
58
908
PHA
909
JSR
947
912
PLA
913
STA
58
915
PLA
916
TAY
917
LDA
#
919
INC
57
19
1: Introduction
921 BNE 930
923 INC 58
925 CLC
926 ADC # 1
928 BNE 895
930 RTS
20
Richard Mansfield
Windows and
Pages
Comparing short BASIC One of the most effective
programs and their machine ways to learn machine lan-
language equivalents is one of guage (ML) is to examine
the best ways to see how machine short routines in BASIC
language works. Using a "win- and then see how the same
dow" into your Commodore 64's * in 8 f accomplished in
memory, this article takes you ML ; ,5 er . M l ther ^ are \
step $ step through the p/cess ™£SS tecl
ofLOADmg and manipulating mu £ in * m i angua g e:
<z« Att routine. looping, branching, compar-
ing, counting, and a few others. And long programs are not created
in a furious burst of nonstop programming. Rather, they are built by
knitting together many small subprograms, short routines which are
as understandable in ML as they are in BASIC. Looking at side-by-side
BASIC-ML examples is the best way to learn ML. Before you know it,
you 11 be able to think in both languages, and you'll have a working
knowledge of machine language.
Peering into Memory
To start things off, type in Program 1. This is called a BASIC loader,
and its function is to POKE a machine language program into RAM
memory. The numbers in the DATA statements are the ML program.
SAVE the program in case things go awry, then type RUN. Nothing
seems to happen. You can then type NEW because the little loader
has done its job: A short ML program is now in memory from address
864 to 875-
Program 1. 64 Loader
800 FOR ADRES=864 TO 875:READ DATTA : POKE ADRES, DAT
TA : NEXT ADRES
864 DATA 162,0,189,0,0,157
870 DATA 0,4,232,208,247,96
Because of the color memory problem (you have to POKE values into
the entire color memory before you can see things), enter this short
BASIC line in direct mode (without line numbers) before trying out
the ML program and after each time you clear the screen:
FOR I = 55296 TO 55552: POKE 1,1: NEXT
1 : Introduction
To see what this ML program does, you can just SYS to the start
of it by typing SYS 864 . If you typed in the DATA statements correcdy ,
you'll see a collection of strange symbols on the screen. Now clear
the screen and type in Program 2. When RUN, it allows you to see
things happening. Some characters are flashing rapidly, some change
only in response to things you typed on the keyboard, some do
nothing. What you're looking at is the first 256 memory addresses
in your computer. The flashing characters (160, 161, and 162, count-
ing down from the top-left corner of the screen) are your computer's
clock. They're what you get when you ask for TI$.
Program 2. The Window
10 SYS 864
20 GETK$
30 GOTO 10
The computer divides its memory into groupings of 256 bytes,
called pages. What you're seeing onscreen is zero page. Stop the
program with the RUN/STOP key and type POKE 868,1. Then RUN
Program 2 again. Now you've changed the zero to a one, and you've
changed the ML program so that it puts page 1 onscreen. You can see
any of the 256 pages in the computer by just POKEing the page
number into address 868.
Comparing BASIC and Machine Language
How does this little ML program send the contents of RAM memory
to the screen? Let's show how we could do it in BASIC and then see
how ML does it:
10 x=0
20 A=0+PEEK(X)
30 POKE 1024+X,A
40 X=X+1
50 IF X<>256 THEN 20
Of course you would probably write a program like this using
a FOR-NEXT loop, but we've distorted normal BASIC style a bit to
more closely reflect the approach used in ML. Look at Program 3 . It's
the kind of disassembly you would see if you used a "monitor" pro-
gram like Tinymon (published in the January 1982 issue of COMPUTE.'
magazine). The first column, starting with 0360 and containing a
series of four-digit hexadecimal (hex) numbers, represents the
addresses in memory where each ML instruction resides. Don't worry
if you don't know hexadecimal notation. For now, it's enough that
22
Introduction: 1
you understand that, in ML, memory addresses perform the same
function as BASIC'S line numbers do in a program LISTing.
Program 3. Monitor Disassembly
0360 A2 00 LDX #$00
0362 BD 00 00 LDA $0000, X
0365 9D 00 04 STA $0400, X
0368 E8 INX
0369 D0 F7 BNE $0362
036B 60 RTS
Program 4. Disassembler
STARTING ADDRESS (DECIMAL ) ? 864
START ADDRESS HEX 0360
864 LDX #
866 LDA ,X
869 STA 1024 ,X
872 INX
873 BNE 866
875 RTS
After the "line number" address, you see some groupings of two-
digit hex numbers. The first group is A2 00. These are the actual
numbers that the computer reads when it executes the ML program.
These numbers are the most elemental form of machine language
and sit in memory at the addresses indicated to their left. Finally, the
LDX #$00 is the disassembly (the translation) of the ML A2 00.
LDX means "LoaD the X register.' ' The X register is like a variable, and
the # symbol tells the computer to load the number zero into the X
— as opposed to the number found at address zero. Without the #,
X would be given whatever number was currently in address zero.
The $ means that the number is in hex notation, not decimal.
Now take a look at Program 4. If you have saved a copy of the
disassembler from the previous section, LOAD it. When it asks you
for "starting address (decimal)," type in 864 and you'll see the same
disassembly as illustrated in Program 4 . Notice that 864 is translated
into hex (0360). Program 4 is nearly identical to Program 3 except that
the numbers between the address and the disassembly are not shown.
The second "line" in Program 4 "LoaDs the Accumulator" with
the item in address zero + X. That is, if X is 5 , the item in + 5 (address
5) is loaded into the accumulator. The accumulator is another "vari-
able" in ML, used to hold things temporarily. Since we're trying to
send all the items in zero page (addresses 0-255) up to the screen
23
1: Introduction
memory so we can see them, our next job is to "STore the Accumu-
lator" at address 1024 + X. (1024 is the starting address of screen
memory on the 64 .) As you can see, we're making X do double duty
here as an "index." It's acting as an offset for both the source items
(in zero page) as well as the target to which we're sending those items
(screen memory).
The next line raises, or increments, X by 1. INcrement X causes
X = X + 1 to take place, so this first time through the loop, X goes
up from to 1. The BNE means "Branch if Not Equal to zero." Branch
is like GOTO, but instead of giving a line number as its target, it gives
an address in memory (866 in this case, the start of our loop). How
does X ever get to zero if it's being INXed each time through the
loop? No single-byte variable in ML can go higher than 255. (Likewise,
no individual memory address in the computer can "hold" a num-
ber beyond 255 . This is similar to the fact that no decimal digit can
ever go higher than 9. After that, the digits "reset" to zero.) As soon
as you've raised X to 255, the next time you INX, it resets itself to zero
and starts over. So line 873 in Program 4 will throw us back to line
866 until we've been through the loop 256 times. Then we'll finally
get to line 875 , where ReTurn from Subroutine sends us out of ML
and back into BASIC where we left off. Notice that SYS-RTS has the
same effect as GOSUB-RETURN, except that the former moves
between BASIC and ML.
Making a Loader Automatically
Program 5 is another useful tool when you're working with ML.
The loader in Program 1 POKEs an ML program into RAM memory
for you; Program 5, "Datamaker," goes in the other direction and
translates an ML program from RAM into a BASIC loader.
After you type it in and SAVE it, try an experiment. To make
a loader out of "The Window," change line 1 in Program 5 to read
S = 864:F = 875:L = 10. S is the starting address of your ML and F
is the finish. Then type RUN. You'll see the loader created for
you onscreen.
The Datamaker destroys itself after it's finished. Notice that the
line numbers created in the loaders made by Datamaker are also the
addresses where the ML will be POKEd. And don't forget to change
the starting and ending addresses in line 800 before SAVEing a
finished loader.
24
Introduction: 1
Program 5. Datamaker
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
1 S=826:F=1023:L=10:REM S&F=ADRES :rera 145
2 PRINT"{CLR}{2 DOWN} " :P0RI=ST0S+48STEP6 : IFI>FTHEN
NEXT: PRINT "GOT07" :G0T06 :rem 217
3 PRINTI; "DATA"; :FORJ=0TO5 : A$=STR$ (PEEK( I+J ) )
:rem 11
4 PRINTRIGHT? ( A$ , LEN ( A$ ) -1 ) " , " ; : NEXT J : PRINTCHR$ ( 20
):NEXTI :rem 227
5 PRINT ,, S="S+48":F="F":L="L":G0T02 :rem 225
6 P0KE198 , L : F0RK=1T0L : POKE 6 3 0+K ,13: NEXT : PRINT "
{ HOME } " : END :rera 248
7 PRINT" {CLR} {2 DOWN} " :F0RI=1T07 : PRINTI : NEXT: L=7 :G
OT06 :rem 155
800 FOR ADRES=826 TO 1023: READ DATTA : POKE AD RES , DA
TTA : NEXT ADRES :rem 82
\bu've seen a little of how ML can be assembled, disas-
sembled, and compared with BASIC. The next article will show you
how a simple ML program is created.
25
J.R. Chaffer
Stealing Characters
from ROM
Plotting bitmapped data Jim Butterfield dropped an
or graphics with machine intriguing hint in the May
language? Want to use standard 1983 issue of COMPUTE!
ROM characters on the same magazine when he used
screen, without tediously bit- the phrase which became
manning each one? Here's a the tltle of this artlcle
mapping eacn one tieres a Normall rom characters
shortcut to do just that. More cannQt £ disl d on
importantly, this article shows the same screen as high .
you how a simple machine reso lution graphics unless
language routine is created eac h byte is carefully mapped
and how it works. out exactly as it exists
in ROM. However, the eight bytes which create each character
are contained permanently in ROM at locations 53248-57343
($DOOO-$DFFF). They can easily be read and transferred to your
bitmap area with a subroutine. This could be done in BASIC; but if
you're doing bitmapping, you've probably already discovered that
BASIC is too slow for this application. As long as you know the
address of each of the desired characters in ROM you'll find this
method of "stealing" characters from ROM just what you need. Many
of these addresses are listed in Table 1.
Plotstring and Dummy Plot
This technique works best if you already have a machine language
subroutine which plots a byte of data by storing it at some specific
address in your 8K block of high-resolution memory. The dummy
routine Plot, called by the example program ("Plotstring"), theoret-
ically does just this; it stores the byte contained in the accumulator
at the RAM address specified by PTR1A and PTR1B (low byte, high
byte format). When you are in bitmap mode, that byte then appears
on the screen at the location corresponding to its address in RAM.
Plotstring initially reads the first data byte in a specified two-byte
character address in ROM, and stores it at your prearranged RAM
location. It then does the same for each of the seven remaining bytes
of the character. You will, presumably, already have figured out the
correct RAM address for the desired screen location. The only other
thing you need is the ROM address from which to start reading the
eight-byte character. (Note that this technique will work for all the
Commodore graphics characters as well.)
26
Introduction: 1
If you're plotting a string of characters, you should place the
string on one of the 25 standard screen-text lines (numbered 0-24).
Also, each character should be located in one of the 40 standard
columns (numbered 0-39). Then, if you simply increment target RAM
pointers between each byte read and stored, after eight bytes the
pointers indicate the correct starting location for the next character.
Plotstring does this by incrementing PTR1A and PTR1B. PTR2A and
PTR2B are pointers to the character addresses in ROM. ROMADS1 and
ROMADS2, as well as the byte following each, point to the start of
a table of double-byte ROM addresses for your intended string. This
table must be built somewhere into your code. BYTECNT is the
counter which insures that you read and store eight bytes at a time.
CHRCOUNT is a count of the number of characters plotted so far, and
is compared to CHRS (the total number of characters to be plotted)
to test for string completion. Note that the timer IRQ is turned off
before switching in ROM for reading.
Here's the subroutine Plotstring, which reads the characters in
ROM, and stores the eight-byte blocks of data, one byte at a time, in
the RAM bitmap. Remember that this routine doesn't actually store
the data in a bitmap. The line JSR PLOT (Jump to SubRoutine Plot)
would do that only if there really was a Plot subroutine. You'll have
to create a Plot subroutine yourself, or refer to Source Code 3,
"Demonote," to see how I created such a subroutine.
This listing is the source code for the Plotstring subroutine; that
is, it shows the program code I entered before I ran it through an
assembler. The assembler, in turn, created the machine language rou-
tine that runs on my Commodore 64. Only through a source code
listing can you see the labels for the various routines called, as well
as comments such as turn off timer IRQ.
Source Code 1. Plotstring
PLOTSTRING: LDA $DC0E
AND #$FE
STA 8DC0E
LDA $01
AND #$FB
STA $01
LDX #$00
STX CHRCOUNT
PLOTCHR LDA CHRCOUNT
ASL A
TAY
; turn off timer IRQ.
; switch character ROM in.
; number of characters
plotted so far.
; multiply by two, to get
; address table offsets.
27
1 : Introduction
PLOTBYTE
NEXTBYTE
¥ T\ A
L.UA.
Ir^-hirt** onH fii.hvti 1 of c hilt*
5 1U U y LC tUlU HI u y Ul \_11*U
I T")"V
ROMADS2 Y
• address in ROM fsee textf).
31A
PTR? A
1 1 XV Z 13
• ctfii*! 1 in nni-nti^r^
, 51U1 1- Ill JJUllH^l 9*
t Tyv
CTV
911
RVTFPIVT
X> I 1 XH_»1t| 1
• mntitpf for eioht hvtes
t r>v
• set 7pfn offset
T Tfc A
LUA
/"DTW^A'* V
^rXXV^AJ, I
5 gCl 11C A. 1 UytC Ul l.lI41al.lCl
from ROM
11 diii rvv/iTi)
TCI}
PT HT
. ond fitnfp in RAM hitman
? allit 91U1C ill IvtjlITX i_/i nil *
INT/" 1
PTTI 1 A
J31NJC.
IV I.' Y'I'R VTI7
1> I . 1 D I 11-
PTniTt
I 1 IV 1 Ij
. inrrpmpnt hitman nointers
9 111V.1 VlUClU JJUlillvi a
XiNC
DTDIJ
r 1 IVj£iY
• itirrpiTipfit ROM nointer
5 dlltlll JCVV^lTl. JJUlllL^l ■
nil x
• liprfpiripnt eitJht-hvte
« VICV^A V-.111\^11L V-1^11L LP y %.\~
tU 1111 Id •
niw
t>t fiTRYTP
I LV^ X X> X X XL
• if not Hone nlot nevt hvte
¥1Vi"
• another eharaeter nlntted
inA
r^Hii rni tivt
CMP
CHRS
; all characters plotted?
BNE
PLOTCHR
; no, plot another.
LDA
$01
; all done now.
OR A
#$04
STA
$01
; switch character ROM out.
LDA
$DC0E
ORA
#$01
STA
$DC0E
; timer IRQ back on.
RTS
; back to calling routine.
Routine Mechanics
I continually use this subroutine to get standard numbers and char-
acters on my bitmap. Of course, the characters are still bitmapped,
but the data is taken directly from the ROM.
If you're new to machine language listings, the labeled variables,
such as CHRS, BYTECNT, and so on, are simply single-byte storage
locations defined by the user. They can be anywhere in free RAM, with
the exception of PTR1A, PTR1B, PTR2A, and PTR2B, which must be
in page 0. You can use locations 251-254 (hex $FB-$FE) and loca-
tion 2 which are not used by BASIC. You can also use locations
139-143 ($8B-$8F) if you're not using BASIC'S RND function.
This routine can be used repeatedly if the ROMADS1 and
ROMADS2 addresses are set by each calling sequence. Note that
ROMADS1 is the first byte of the two-byte address immediately fol-
28
Introduction: 1
lowing the LDA in the line, LDA ROMADSl,Y; the LDA here is byte
185 ($B9). Likewise, ROMADS2 is the byte immediately following
the LDX in the next line, and the LDX is coded as byte 190 ($BE). So
what we are doing here is modifying the subroutine itself as part of
the calling sequence. Actually, four bytes must be set by the calling
routine: (1) The ROMADS1 byte; (2) the byte just following ROMADS1 ;
(3) ROMADS2; and (4) the byte immediately after ROMADS2.
Let's say you want to plot the string, Note 1: near the upper-left
corner of your bitmapped screen. And let's say your bitmap storage
area is from 57344 to 65343 ($E000-$FF3F), which is under the
Kernal ROM. You're starting the string in text column one, on line
one. (Remember that column and line numbers run from to 39 and
from to 24, respectively.) If you work out the address for this
screen location, you will find that the starting byte is 57672 ($E148).
Let's also say your character ROM address table for the string Note 1:
has been stored in RAM as in Table 2, starting at location 49152
(SC000). A functional calling sequence would be as follows:
Source Code 2. Calling Sequence
PLOTNOTEl
CONT
LDA
#$48
LDX
#$E1
STA
PTR1A
STX
PTR1B
LDA
#$C0
LDX
#$00
STA
ROMADS1 + 1
STA
ROMADS2 + 1
STX
ROMADS1
INX
BNE
CONT
INC
ROMADS2 + 1
STX
ROMADS2
LDY
#$07
STY
CHRS
JSR
PLOTSTRING
lo-byte, screen location,
hi-byte, screen location.
hi-byte, Table 2 start,
lo-byte, Table 2 start,
address = ROMADS1 + 1
address = ROMADS2 + 1
lo-byte of address.
ROMADS pointers set.
seven characters in string,
go plot "Note 1:"
Each string you plot must have its ROM character address table
stored somewhere in RAM, similar to Table 2. Note that the address
bytes are stored in standard lo-byte, hi-byte format. Thus, they appear
to be backwards when compared to the addresses given in Table 1.
This can be switched, if you modify Plotstring accordingly.
29
1 : Introduction
Faster and Easier
If you bitmapped each character directly, you would still need a sub-
routine to do it, and your data table would have eight bytes for each
character instead of two. In addition, you would have to work out,
or copy, the bitmap for each individual character. With a routine
like Plotstring, all you need is a table of their ROM addresses. The
addresses of the most common characters are listed in Table 1.
The calling sequence can be summarized as follows:
1. Set screen location pointers (PTR1A and PTR1B).
2. Set the ROMADS pointers (four different bytes) to indicate the
start of the string address table.
3. Set the number of characters in the string.
4. JSR to Plotstring.
It's not necessary to use an exact copy of Plotstring as it appears
in this article. If you write your own routine, however, be sure to
switch the timer IRQ out before switching the ROM in for reading.
Also, make sure you turn the timer on again after switching the ROM
out, or you'll probably not be able to use the keyboard.
You don't need to worry about the video bank fouling up the
ROM addresses, either. If you use the absolute addresses given in Table
1, you'll read ROM characters correcdy with this scheme regardless
of which video bank you're using.
30
Introduction: 1
C/5
z
1
w
N
I
Q
w
U
w
73
«5
W
S3
|
w
ft
o
W W
BUOw«
OS00 00 90U
ar> «i (A
(4 U U W W
OOOflQ
©
o
o
u
3
Q
x
Q
x
X
«*
o
<!
as.
X
X
r-
©
Q
©
ir\©«T\©ir\©ir\©«f\©ir>©»r\©ir\©ir\©«f\©ir\©iA©iA
©©0©©©©iMi-(iHF*i-<»H>-i»NiH*Mi-ii-Hi"H>"*f-(i-i»Mi-i
©©©©©©©©©©©©©©©©©©©©©©©©©
X
o
Q
©
©
o
©
X
Q
%
x
Q
©
©
u
31
1 : Introduction
o
Q
X
CO
©
o
pa
PS OS PS
W3 <fl 1/3
2 9 2
PS OS OS
13
V3
o
© ir\ ©
Ti © «T\ © 1T\ ©
0\
ON © O -
h N N N
N N N M
o
o o o ©
© © © © © ©
»s
©
© ©
y
y y
D8
"a
o fl
U H
X
©
© ©
fM
i
\0
§§
i
H
i i
*H
o
©
o
o o
©
© ©
u
y y
U
y y
© ,9 ©
$2 $2 Q w
h-osOaQsit^HpnvocK
o©©©©©©©©
uuuuuuuuu
o
y
© o
o ^ °^
x 2 w w
w Q w x
N N N (ft
© © © ©
y y y y
32
n
n
n
n
Introduction: 1
Q Q
n
a a 2 9
OiAOifiOifiO^OifiOifiOifiOiAOirO^O^O^O^OiT
OOOOOOOOOOOOOOOOOOOOOOOOOOOO
n
o 00
< 00
I I
O ©
8 w
it, m
O W
6s u
PC PTi
© ©
U U
u
Q
3
9
Q
E©©E©°»»
noo^moo^oo^c^W
©©©©©©©©©©©©
u.ouuuuuuuuuu
o ©
u u
n
33
1 : Introduction
«
«^ m n H M
g
<-> g u < & S
P3 a 3 u «
U
□
□
U
i
©if\©iri©ir\©ir\©«f\©ir\©w\©i^©ir\©ir\©ir»©ir\©ir\©«r\
^^i~~l^«000Nff\©©^«^NMfr>ff)-*^<MMr\vavci^l^«»O\O\
©©©©©©0©©0©©©0©©©©©©©©©©©©©©
©
u
«
©
u
es§g§e«g
•^^©^©"-•©^Svava
I i ' « I I I I I L I I I
o©ooooooo©©©©
uuuuuuuuuuuuu
So w oo
\0 ©
UQu
N ^ \0
h- 1^-
© © ©
uuu
u « £
w » Q
U"\ «Ti ©
I 1 I
00 >«J U
1^- 1^
© © ©
34
U
u
□
u
Introduction: 1
as
o
i
S! °
5
O
i
o
* B4
M Pi
S [I]
M5
y
v> v> ^ v>
©w\©«r\©ir\©>r\©ir\©iri©«r\©ir\©ir\©«r\©ir\©ir\©»r©«f\
O©pHFHNNfTifr>>*^<irnr\ , o^h-r-«X0\0s©©'^^MNjftjft
1M v$<
© © I
w ©
x
© ©
u u
y
y
Q
«
©
© ©
o\ Q ©
© 00 \Q
M 4
00 00
© ©
y y
r- os y
oo oo x
© © ©
y y y
00
8
»©E3©«oEft©o
ir\«riOMT\«ri©'-'»^>'SON
l
I
wopi-^viob^yw
00CnCN^C\ONOSONON_.
ooo©©©©©©©
yyyyyyyyyy
35
1 : Introduction
05
as
o
7
it
Hi
O
.. o
W 00
Q u
M
03
o
N-l J 2
... u w j ... .„
©«f\©tf\©«i*i©ir\©if\©ir\©ir\©ir\©«r\©ir\©w"\©tf\©tr\©ir\
•*vfirnnvo\oi^i^«»osO\o©^i-(NNff>pn^>*ifMr\vo\oi^i^
©©©©©©0000©©©©©0©©0©000©©©©©
o
00 ©
oo «rw©
I I I
m ir\
O y © 03 ft
ft £ © ft *H
0\ «TN IT\ M 00
<J 00 «< 00 ■< <
© s s © © ©
UUUOUU
e
rt oo o
■ i i i
»h m ve
PQ 03 03 03
© © © ©
uguu
ft E
© ON
^ ft
<< © 00 Q © a
ob Os P3 W © n
03 CQ 03 03 03 U U
© O © O © © ©
UUUUUUU
36
Introduction: 1
%4
w
Q
O
2
5!
2
w
u
W
Q
O
2
o
Q
Q
J$ 3$
QhQ
-1 W3 hJ
o
as
u
«5
©ir\©«r\©ir©»T\©>^©»r>©»^©'^© , ^© , ^©!C \r9!£© ,rv
©©©©©©0©©©©©©©©©©©©©©©©©^****"*
»UgP5
v h O h
C\ IT\ ON V\ *3
-0 oc < oo ■<
i i i l A
rft ir\ h- G\ 05
eg
© U ft
M OS-* ?? 2v0
(J U 6 N fft^
UUQOOO
„„.„_._©©©©©©
ft ft
©
0\U
» OS
W ft
© ©
00
Q
_ ©
u u
<5 U
Q Q
© ©
©
v©
Q O
oo oo g
< oo •< 00 <!
©
Q
©
ft ft
© ©
0\U
ft ft ft
© © ©
u u u
1 : Introduction
>> H*
MO © _ "
«QQ«QfiwQ
fJ O <» OS
►J Q
O Q O X
0»Ow
N O
P o
SflSODgO
QQwQQ«Q
<«. <« ^ ^
1
V3
w
pa
©«r\Oir\©ir\0«r\0>r\©«r\©ir\0«f\0«f\©»f\©iri©ir\©ir\o«r\0
MMff>ff>-*^<ir\if\va^ot^t^«»0\C\©©-^^NMfr>ff>^<^<if\iri^
©o©©©o©©doooo©©©'4i-ii-ii-i'4i-ii-ii-i<-iv4iHv<FH
Q
Q
© ©
o\ Q
O 00
I I
fa fh
w ft
© ©
©
Q
Q
Q
U ©
S ©
os Q
On U fa «■< -*
fa fa fa fa O ©
© © © © FF FN
uuuuuu
9 onQ Q onQ ©
< N 00 < O 00 NO
©
Q
© FH
© ©
Q Q
-F ft FH
< fq 00 00
»r\ oo < fa
© © © © ©
i4 f: Fl H Fl
uuuuu
Q 9 Q
So q
S3 fr> n 2 ©
© © © © © ©
9 OnQ 9 §0 ©
<!©»•<©» no
1 I I K JL i I
n «r\ h~ <C Q fa m
H H N H H F( N
F H Fl M H
uuuuouu
38
n
Introduction: 1
n
n
S S3
w o
lf\OlAOlTiO^O<AOirO
'Or-|--00XG\G\©©^'-<< s <
u
O \Q cj
i— , OUUftO
I OS «r\ »2 o o o
I I I I ' I
ffi «f\ r- On S3 14
nM ^ N <M N M
1-1 i-H 1-H 1-H iH 1-1
i ) uuuuuu
1^ N
© ^ u §
so a o g
o
pj |^ — O
§ « 5 u n v g E g u
n
39
u
1 : Introduction
To actually see this ML subroutine in action, you need to enter
two programs. First, type in and RUN Program 1, "Plotstring Loader."
This program POKEs the required values into the appropriate memory
locations. If you've entered some of the DATA incorrectly, the check-
sum included will tell you there's an error. Next, type NEW, enter
Program 2, "Note 1:," and RUN it. What you'll see is a message
telling you to press the space bar. As soon as you do, the machine
language subroutine places the characters spelling Note 1: on the
screen. It may not seem impressive, but what you've just done is
steal characters from ROM and place them on a bitmapped screen.
Painless machine language.
Program 1. Plotstring Loader
For mistake-proof program entry, besureto read "The Automatic Proofreader," Appendix C.
10 FOR 1=49152 TO 49454 :READ A
20 CK=CK+A
30 POKE I, A: NEXT I
40 IF CK<>41733 THEN PRINT "ERROR IN DATA"
50 END
49152 DATA 112,208,120,216,160,216
49158 DATA 040,216,000,209,136,209
49164 DATA 208,209,032,166,192,032
49170 DATA 195,192,032,226,192,169
49176 DATA 072,162,225,133,251,134
49182 DATA 252,169,192,162,000,141
49188 DATA 087,192,141,090,192,142
49194 DATA 086,192,232,208,003,238
49200 DATA 090,192,142,089,192,160
49206 DATA 007,132,139,032,063,192
49212 DATA 076,035,193,173,014,220
49218 DATA 041,254,141,014,220,165
49224 DATA 001,041,251,133,001,162
49230 DATA 000,134,140,165,140,010
49236 DATA 168,185,000,000,190,000
49242 DATA 000,133,253,134,254,160
49248 DATA 008,132,141,160,000,177
49254 DATA 253,032,141,192,230,251
49260 DATA 208,002,230,252,230,253
49266 DATA 198,141,208,237,230,140
49272 DATA 165,140,197,139,208,211
49278 DATA 165,001,009,004,133,001
49284 DATA 173,014,220,009,001,141
49290 DATA 014,220,096,120,133,142
49296 DATA 165,001,041,253,133,001
49302 DATA 165,142,160,000,017,251
49308 DATA 145,251,165,001,009,002
49314 DATA 133,001,088,096,169,224
:rem 23
:rem 39
: rem 10
:rem 56
: rem 60
: rem
133
: rem
142
: rem
150
: rem
161
: rem
147
: rem
146
: rem
161
: rem
156
: rem
149
: rem
143
: rem
142
: rem
137
: rem
122
: rem
119
:rem
133
: rem
134
: rem
139
: rem
140
: rem
132
: rem
153
: rem
155
: rem
134
: rem
133
: rem
135
: rem
136
: rem
130
: rem
136
: rem
154
u
□
u
u
40
u
u
U
u
u
n
i— ) Introduction: 1
j ,
n
49320
DATA
133 . 252 . 169 . 000 .133.251
• rem
135
49326
DATA
162,031,168,145,251,200
: rem
142
49332
DATA
208,251,230,252,202,208
: rem
137
49338
DATA
246 , 145 , 251 , 200 , 192 , 064
: rem
151
49344
DATA
208,249,096, 169,200,133
: rem
159
49350
DATA
252 ,169,000, 133 , 251 , 168
: rem
146
49356
DATA
162 .003 .169. 203 . 145 . 251
• rem
148
49362
DATA
200 . 208 .251. 2 30. 252. 202
• rem
132
49368
DATA
208 . 246 . 145 . 251 . 200 . 192
• rem
154
49374
DATA
232 . 208 . 249 .096 . 173 . 024
* rem
161
49380
DATA
208,133,002,169,040,141
• rem
139
49386
DATA
024,208,173,002,221,009
: rem
143
49392
DATA
003 . 141 . 002 . 221 . 173 . 000
• rem
124
49398
DATA
221,041,252,141,000,221
: rem
133
49404
DATA
173,017,208,009,032,141
: rem
140
49410
DATA
017 , 208 , 096 ,173,017, 208
: rem
150
49416
DATA
041,223,141,017,208,165
: rem
142
49422
DATA
002,141,024,208,173,002
: rem
128
49428
DATA
221,009,003,141,002,221
: rem
127
49434
DATA
173,000,221,009,003,141
: rem
128
49440
DATA
000,221,096,169,000,133
: rem
134
49446
DATA
198,165,198,240,252,032
: rem
165
49452
DATA
005,193,096,013,013,013
: rem
139
n
/ i
n
n
Program 2. Note 1:
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
90 POKE 53272,23 : rem 44
100 PRINT" {CLR} {DOWN} { RIGHT} {OFF}{27 SPACES}":PRI
NT" {RVS} DEMO TO SHOW PLOTSTRING " : rem 113
110 PRINT" {RVS} IN ACTION. 114 SPACES}" : rem 248
120 PRINT : PRINT " {RVS} PRESS SPACE BAR TO SEE
{2 SPACES }": PRINT " JRVS} 'NOTE 1:'{15 SPACES}"
:rem 151
130 POKE 198,0:WAIT 198,1:SYS 49166:GOT0 120
:rem 120
140 END :rem 108
41
1 : Introduction
Table 1. Common ROM Character Addresses
Character Address Character Address Character Address
A
a r\f\f\o
$DUuo
space
SDIOO
a
5SD808
T>
D
ISDOIO
SD110
b
$D810
c
if T\f\ 1 O
SD018
%
SD128
c
$D818
D
»D020
&
SD130
d
$D820
E
SD028
SD138
e
SD828
F
»D030
(
SD140
f
SD830
G
»D038
)
SD148
g
$D838
T T
rl
JSD040
+
8D158
h
$D840
I
SD048
SD160
i
SD848
J
SD050
$D168
j
SD850
K
SD058
SD170
k
SD858
L
SD060
/
SD178
1
SD860
M
iff r\A/
S5D068
SD180
m
$D868
N
SD070
1
S5D188
n
$D870
O
SD078
2
$D190
o
SD878
P
SD080
3
SD198
P
$D880
a
«r>flSS
JPUUOo
8D I AU
q
6r\ooo
6L)o88
R
SD090
5
J5D1A8
r
SD890
S
SD098
6
SD1B0
s
SD898
T
SDOAO
7
SD1B8
t
SD8A0
U
SD0A8
8
SD1C0
u
$D8A8
V
SDOBO
9
SD1C8
V
$D8B0
w
8D0B8
SD1D0
w
SD8B8
X
SDOCO
»
SD1D8
X
$D8C0
Y
SD0C8
SD1E8
y
SD8C8
Z
SDODO
?
SD1F8
z
SD8D0
Table 2. ROM Addresses for Note 1:
Memory Location
Address
Character
SCOOO
$70 SDO
N
SC002
$78 $D8
o
SC004
SAO $D8
t
JSC006
$28 $D8
e
SC008
$00 $D1
space
*COOA
$88 $Dl
1
SCOOC
$D0 $D1
42
Chapter 2
Programming
Aids
□
□
□
□
□
D
□
Brent Anderson and Sheldon Leemon
BASIC Aid
Twenty of the most useful We'd all like to customize
programming aids, from search- BASIC to fit our individual
ing and replacing strings to needs. It's not difficult to
line renumbering are included think of some valuable pro-
in this one package. Several gnunming aids that were
DOS support commands also ^ ^Tmte^auto- 8
make it simple to seethedirec- ^ -J^SJ °"
tory (without affecting the searching and facing,
program in memory), rename merging, and deleting line
files, or load and run programs. xx^ts, are just a few. Some
Mistake-proof entry is easy of the short routines else-
when you use MLX to type where in this book add
in this program. just one or two of these
functions. "BASIC Aid,"
however, gives you 20 new ways to help you write BASIC programs.
Even more importantly, they're all in one package. You don't have
to search and somehow splice together several different programs.
If you do any BASIC programming at all, this package will be one
of your most valuable utilities. It takes up nearly 4K bytes of memory,
but it's safe from BASIC. You can still program normally. And by
using MLX, the Machine Language Editor found in Appendix D, you
can be assured it's entered correctly.
Some History
The program was originally written for the PET/CBM computers by
James Strasma, and later modified by F. Arthur Cochrane. It's become
one of the most popular programs available for Commodore com-
puters. Until now, unfortunately, there hasn't been a version written
expressly for the 64. Brent Anderson, who translated this program
to the 64, has been a user of Commodore computers since 1981,
when he joined Strasma and others to form the Central Illinois PET
Users Group. He currently heads ATUG, a Commodore users
group dedicated to exchanging information dealing with machine
language programs.
MLX and BASIC Aid
You'll use MLX to enter BASIC Aid. Before you begin to type in this
program, make sure you read Appendix D. You'll also need to type
in and save a copy of the MLX program to tape or disk. Once you've
done that, load and run MLX. It will ask for the starting and ending
45
2: Programming Aids
addresses for BASIC Aid. They are:
Starting address: 49152
Ending address: 52997
Once you've typed in those numbers, you're ready to begin entering
BASIC Aid. "Vou don't have to enter it in one session; you can stop
and pick up where you left off any number of times. Refer to the
instructions in Appendix D for details.
Once you've got BASIC Aid typed in (which may take you several
sessions — it's a long program), make sure you save it to tape or
disk. It's then ready to use.
Load BASIC Aid as you would any other completely machine
language program by typing LOAD "filename",8,l. Then type NEW
to reset the BASIC pointers. You start it by entering SYS 49152. BASIC
Aid uses the wedge technique to add the following commands to
BASIC. Since the wedge can slow execution of a program, all of these
commands work only in direct mode (without using line numbers).
An additional feature lets you pause or stop any BASIC Aid com-
mand that displays to the screen. To pause the display, simply hold
down the SHIFT key. To stop it, hit the SHIFT LOCK key or the space
bar. To release, unlock the SHIFT, or hit the Commodore key. Press-
ing the STOP key aborts the feature entirely.
Programming Aids
Each of the aids supported by BASIC Aid is listed below. The syntax
of the command is printed, and a short explanation of what each does
is also included. Many of the features are obvious, and little infor-
mation is necessary. Others, such as the CHANGE option, are more
complex and are explained in greater detail. At the end of the pro-
gram, you'll find a quick reference card you can cut out and place
next to your computer.
AUTO
Syntax: AUTO line increment (to turn on)
AUTO (to turn off)
AUTO automatically numbers the lines of your BASIC program.
You start the process by typing AUTO, followed by a line increment
from 1 to 127. The first line number must be entered manually. The
next line number in the sequence automatically appears from that
point on. For example, if you enter AUTO 10, and then the line 10 REM
THIS IS THE FIRST LINE, the line number 20 appears under the 10,
ready for you to type in the next line. To turn this feature off, simply
enter AUTO without a line number increment.
46
Programming Aids: 2
BREAK
Syntax: BREAK
The BREAK command is used to enter a machine language
monitor like Micromon or Supermon, if such a program has been
previously installed.
CHANGE
Syntax: CHANGE/search string/replacement string/, line number
range
or
CHANGE "search string"replacement string", line number
range
CHANGE replaces one string of characters (the search string)
with another string of characters (the replacement string). Each line
in which the string is replaced is displayed on the screen. If the
optional range of line numbers is specified, the search string is
replaced within that range. Otherwise, the search string is changed
to the replacement string at every occurrence within the program.
Line number ranges should be specified as they are in the LIST com-
mand. For instance, CHANGE/FIRST STRING/SECOND STRING/,
-100 changes the string in lines 0-100; CHANGE/FIRST STRING/
SECOND STRING/, 100-200 changes it within lines 100-200; and
CHANGE/FIRST STRING/SECOND STRING/,200- changes it from
line 200 to the end of the program.
Two different delimiters can be used to set off the search and
replacement strings. This is because BASIC stores keyword com-
mands (such as PRINT) differendy than it does the same combination
of characters when they appear in quotes or as DATA. If it didn't, it
would get terribly confused by statements such as PRINT "PRINT".
It would try to execute the second PRINT, rather than printing it
on the screen. The CHANGE command lets you decide which type
of string you wish to change. If the backslash character is used to
separate the two strings, BASIC reserved keywords are recognized as
such. If quotation marks are used, all text is treated as strings of
characters. For example, if the program in memory is:
10 PRINT "ALL THAT THIS PROGRAM DOES IS PRINT"
then the command CHANGE/PRINT/REM/ alters the program to:
10 REM" ALL THAT THIS PROGRAM DOES IS PRINT"
while the command CHANGE "PRINT"OUTPUT CHARACTERS"
changes the program to:
47
2: Programming Aids
10 PRINT "ALL THAT THIS PROGRAM DOES IS OUTPUT CHAR
ACTERS"
In the first case, only the tokenized PRINT command is recognized,
while in the second, only the string literal "PRINT" is changed.
Keep in mind that every occurrence of the string is changed, even
if that string appears as a substring in the middle of a word. For
example, CHANGE/TO/FROM/ converts the line
100 PRINT "GET THE MESSAGE TO TONY"
to
100 PRINT "GET THE MESSAGE FROM FROMNY"
Such an error could be avoided by including the spaces around the
word in the search and replacement strings (CHANGE/ TO /
FROM /would have the desired effect). When in doubt, look for all
occurrences of the search string with the FIND command before
using CHANGE, so that no unwanted substrings crop up.
COLD
Syntax: COLD
The COLD command is used to cold start the computer. This
means that the computer goes through all the steps it normally would
when you turn the power off and on again, except that the con-
tents of memory remain intact. Sometimes, when certain memory
locations that BASIC uses have been changed, commands no longer
function correctly. By entering COLD, then initializing BASIC Aid with
a SYS 49152, and entering the OLD command, you can get a fresh
start. COLD can also be used to disengage BASIC Aid and all other
machine language programs like monitors that affect the operation
of the computer.
CRT
Syntax: CRT
This command sends text and graphics characters to the printer
exactly as they appear on the screen. This version accommodates
only a Commodore printer connected as device number 4.
DELETE
Syntax: DELETE line number range
This command deletes a number of BASIC program lines at once.
The line number range uses the same format as the LIST command.
For example, DELETE -100 deletes all lines up to and including line
48
Programming Aids: 2
100, DELETE 100-200 deletes those two lines and all lines in between,
and DELETE 200- deletes lines 200 and up.
DUMP
Syntax: DUMP
DUMP lists the variables used in a BASIC program in the order
in which they were created, as well as shows their current value.
Only scalar (nonarray) variables are displayed. DUMP can be handy
for testing the effect of changing the value of a variable in a running
program. Just hit the STOP key, type DUMP to check the current value
of a variable, edit and enter a new value for the variable, and type
CONT to continue the program using the new value.
FIND
Syntax: flND/search string/, line number range
or
FIND "search string", line number range
The FIND command searches the BASIC program for a string
of characters, and displays the program lines in which the string
appears. This command displays every occurrence of the string,
unless a limiting range of line numbers is specified. The format of this
number range is the same used by the LIST command. If the back-
slash character is used to enclose the string, BASIC keyword tokens
within the string are recognized as such, but if the string is enclosed
in quotes, such words are treated as their literal string of characters.
For examples of this distinction, see the CHANGE command.
FLIST
Syntax: FLIST "BASIC program filename"
This reads a BASIC program file on disk and lists the program to
the screen without entering it into memory or otherwise affecting
the program currently in memory. FLIST allows you to make certain
you've got the right program before you try to LOAD or MERGE it.
HELP
Syntax: HELP
HELP displays the BASIC program line that was executing when
the program was stopped, and highlights in reverse video the last
character read by the program. It's helpful for finding which state-
ment of a multistatement program line caused an error. On the 64
it's particularly useful when the screen has been changed from text
to high-resolution graphics, and error messages cannot be read. Since
changing the screen back to text with the RUN/STOP-RESTORE
49
2: Programming Aids
combination also erases the error message, HELP can show where
the error occurred.
HEX
Syntax : HEX $ hexadecimal number
or
HEX decimal number
You can convert decimal numbers to hexadecimal notation and
vice versa, with this feature. If the number entered is preceded by a
dollar sign, it's considered a hexadecimal number in the range $0000
to SFFFF, and its decimal equivalent is displayed. If no dollar sign is
entered, a decimal number in the range to 65535 is converted to
hex and then displayed.
KILL
Syntax: KILL
This disables BASIC Aid. To restart the program, type SYS 49152.
MERGE
Syntax: MERGE "BASIC program filename"
This command reads a BASIC program file from disk, lists each
line on the screen, and enters the line just as if it had been typed in
from the keyboard. To use MERGE, first load one program into the
computer's memory. Do not run it. Then type MERGE "filename",
using the filename of the program you want to merge into the first.
The program lines using numbers not already found in the first pro-
gram (the one in memory) are added, while those that duplicate
numbers already in use will replace those lines.
OLD
Syntax: OLD
As you might have guessed, the OLD command is used to undo
the effects of an inadvertent NEW command. As long as no program
lines are entered after NEW has been entered, OLD can recover the
program. It can also be used to restore the program after a cold start
(either from the COLD command, or using a reset switch connected
to the user port for recovering from a crash).
OFF
Syntax: OFF
This command restores the normal IRQ vector, and turns off the
interrupt-driven functions, namely, program scrolling, quote mode/
50
Programming Aids: 2
insert mode escape, and keyprint. (See the description of these
functions below.)
READ
Syntax: READ "sequential filename"
The READ command reads a sequential file from disk and
prints its contents to the screen. It can be used for viewing text
or data files.
RENUMBER
Syntax: RENUMBER
or
RENUMBER starting line number
or
RENUMBER starting line number, line increment
RENUMBER completely renumbers the BASIC program in
memory, including line number references in GOTO, GOSUB, and
IF-THEN statements. If no numbers are entered after RENUMBER,
the program will be renumbered starting at line 100, with line incre-
ments of 10. You can specify a different starting line number or a
different increment value.
REPEAT
Syntax: REPEAT
This command is used to toggle the repeat key function. When
BASIC Aid is started, all keys repeat if held down. Entering REPEAT
disables this feature for all but the cursor and space keys; typing it
again reenables it.
SCROLL
Syntax: SCROLL
SCROLL enables all of the interrupt-driven keystroke commands.
These are:
1. Program scrolling. When you move the cursor to the bottom-left
corner of the screen and press the cursor down key, the listing
will roll up, and the next program line will be printed at the bottom
of the screen. If you move the cursor to the top-left corner of the
screen and press the cursor up key combination, the listing will roll
down, and the previous program line will be displayed at the top.
2. Quote mode/Insert mode escape. By pressing the fl key, quote
mode and insert mode are canceled, allowing you to move the
cursor normally.
' 51
2: Programming Aids
3 . Keyprint. This function allows you to send the characters currently
on the text screen to a printer by pressing the f 8 key (SHIFTed f7).
In effect, this executes the CRT command (see above), but can be
used while a program is running. With these you can make a hard
copy of output normally only printed on the screen, such as pro-
gram instructions. You must be careful, however, not to try to use
this function while serial bus operations such as disk accesses are
taking place, since this will lock up the system. This means that
the keyprint feature cannot be used to print the directory displayed
by the DOS wedge, or to print programs or text displayed by the
READ or FLIST commands. Likewise, trying to use it without a
printer connected may lock up the system or abort the program
that is running.
When BASIC Aid is started, all of these interrupt-driven functions
are enabled. During the course of programming, however, there are
several ways in which the normal interrupt can be restored (such as
by hitting the RUN/STOP-RESTORE combination, or by using the
OFF command). To restart these functions, use the SCROLL command.
START
Syntax: Start "program filename"
The loading address for program files is located in the first two
bytes of the file. This command reads those bytes from the specified
program file on the disk and displays the starting address in decimal
and hexadecimal. START is handy for finding where a nonrelocat-
able machine language program (one that is loaded with the LOAD
"NAME",8,1 format) starts.
DOS Support Commands
Syntax:. > disk command or @disk command
> $ or @$ (directory)
/ program name (LOAD)
t program name (LOAD and RUN)
BASIC Aid also supports many of the commands found in the
DOS support program. The greater than ( > ) and commercial at (@)
signs are used to communicate with the disk on the command
channel. Using the symbol alone reads the error channel and prints
it to the screen. Entering the symbol followed by a dollar sign prints
the directory on the screen without altering the program in memory.
Typing in the symbol followed by a command string sends that
command to the disk, just as if you had typed in the BASIC line
OPEN 1,8,15: PRINT#l,"command string": CLOSE 1. These
commands include:
52
Programming Aids: 2
1. > SO:filename. Erases the named file from the disk. If wildcards
such as * or ? appear in the filename, more than one file may
be erased.
2. > ROmew filename = old filename. Changes the name of the disk
file from old filename to new filename.
3. > CO-.new filename = old filename. This command copies disk
file old filename to the file new filename.
4 . >V0. Performs a disk validation or collection, which reclaims disk
blocks marked as in use, but which are in fact not used.
5 . > NO. disk name, ID. Formats the disk for use, erasing all informa-
tion that it previously contained, and giving it the title and disk
ID number entered in the command.
Two additional DOS support functions are included. Entering the
backslash (/) followed by the program filename loads that program
from disk. Typing the up arrow ( t ) followed by the program filename
loads and runs the program.
BASIC Aid
Be sure to read ' 'Using the Machine Language Editor: MLX, ' ' Appendix D, before typing in
this program.
49152 :169, 000, 141, 136, 003 ,141, 078
49158 : 137, 003, 173, 243, 206, 174, 174
49164 : 244, 206, 224, 160, 176, 007, 005
49170 : 133, 055, 134, 056, 032, 089, 005
49176 : 166, 162, 015, 189, 043, 192, 023
49182 : 149, 115, 202, 016, 248, 162, 154
49188 :019, 032, 059, 192, 076, 089, 247
49194 : 193 , 230 , 122 , 208 , 002 ,230,003
49200 : 123, 173, 255, 001, 076, 154, 062
49206 : 192 , 234 , 076 , 191 , 192 , 189 , 104
49212 :047, 206, 240, 006, 032, 210, 033
49218 : 255, 232, 208, 245, 096, 208, 030
49224 : 014, 120, 162, 023, 189, 162, 230
49230 : 227, 149, 115, 202, 016, 248, 011
49236 :076,186,199, 076, 217, 205, 019
49242 : 173 , 141 , 002 , 041 , 001 , 208, 144
49248 :249, 032, 125, 192, 208, 020, 154
49254 :032, 125, 192, 240, 251, 201, 119
49260 :255, 240, 247, 032, 125, 192, 175
49266 : 201 , 255 , 208 , 249, 169, 000, 172
49272 : 133, 198, 076, 225, 255, 173, 156
49278 :001, 220, 205, 001, 220, 208, 213
49284 : 248, 201, 239, 096, 133, 098, 123
49290 :162, 144,056,032,073, 188,025
49296 :076 , 221 , 189 , 230 , 135 , 208 , 179
53
2: Programming Aids
49302 :002, 230, 136, 096, 133, 131, 110
49308 :134, 151, 186, 189, 001, 001, 050
49314 : 201, 140, 240,035, 166, 123,043
49320 : 224, 002, 240, 011, 134, 138, 149
49326 : 166, 122, 134, 137, 076, 183, 224
49332 : 192, 164, 133, 166, 151, 165, 127
49338 : 131, 201, 058, 176, 200, 201, 129
49344 :032, 240, 003, 076, 179, 227, 181
49350 : 076 , 115 , 000 , 189 , 002 , 001 , 069
49356 : 201, 164, 208, 231, 032, 183, 199
49362 : 192, 144, 077, 165, 131, 016, 167
49368 :002, 230, 122, 162, 000, 134 ,098
49374 : 127, 132, 133, 164, 122, 185, 061
49380 : 000 , 002 , 056 , 253 , 086 , 206 , 063
49386 : 240, 019, 201, 128, 240, 019, 057
49392 s 230, 127, 232, 189, 085, 206,029
49398 : 016 , 2 50 , 189 , 086 , 206 , 208 , 177
49404 : 228 , 240 ,182,232, 200 , 208 , 006
49410 : 224, 132, 122, 104, 104, 165, 085
49416 :127, 010, 170, 189, 192, 206, 134
49422 : 072 , 189 , 191 , 206 , 072 , 032 , 008
49428 : 181 , 192 , 076 , 115 , 000 , 032 , 104
49434 : 207 , 195 , 141 , 136 , 003 , 076 , 016
49440 :002, 194, 104, 104, 165, 131, 220
49446 : 032 , 107 , 169 , 240 , 041 , 173 , 032
49452 :136, 003, 240, 036, 024, 165, 136
49458 : 020 , 109 , 136 , 003 , 133 , 099 , 038
49464 : 165 ,021 , 105 ,000 , 032 , 136 , 003
49470 : 192 , 162 , 000, 189 , 001 , 001 , 095
49476 :240, 006, 157, 119, 002, 232, 056
49482 : 208 , 245 , 169 , 032 , 1 57 , 1 19 , 236
49488 :002, 232, 134, 198, 076, 159, 113
49494 : 164, 208, 020, 120, 173,245,248
49500 :206, 141, 020, 003, 173, 246, 113
49506 : 206 , 141 , 021 , 003 , 032 , 031 ,020
49512 :206, 088, 076, 116, 164, 076, 062
495 18 : 2 17 , 205 , 044 , 141 , 002 , 240 , 191
49524 : 045, 032, 133, 198, 162, 000, 174
49530 : 134, 199, 134, 198, 134, 197, 094
49536 :228, 212, 240, 004, 134, 212, 134
49542 : 208, 004, 228, 216, 240, 016, 022
49548 :134, 216, 230, 198, 164, 211, 013
49554 : 136 , 169 , 032 , 145 , 209 , 169 , 238
49560 : 157, 141, 119, 002, 165, 197, 165
49566 : 201 , 003 , 240 , 206 , 201 , 004 , 245
49572 :240, 210, 173, 248, 206, 072, 033
49578 : 173 , 247 , 206 , 072 , 008 , 072 , 180
49584 :072, 072, 076, 049, 234, 032, 199
49590 :061,195, 165,095, 166,096,192
54
Programming Aids: 2
49596 :133, 036, 134 ,037, 032, 019, 067
49602 : 166, 165, 095, 166, 096, 144, 002
49608 :010, 160, 001, 177, 095, 240, 115
49614 :004, 170, 136, 177, 095, 133, 153
49620 : 122, 134, 123, 165, 036, 056 ,080
49626 z 2 29 , 122 , 170 , 165 , 037 , 2 29 , 146
49632 : 123, 168, 176, 030, 138, 024, 115
49638 : 101, 045, 133, 045, 152, 101, 039
49644 : 046, 133, 046, 160, 000, 177, 030
49650 : 122, 145, 036, 200, 208, 249, 178
49656 :230, 123, 230, 037, 165, 046, 055
49662 : 197, 037, 176,239,032,051,218
49668 .-165,165,034,166,035,024,081
49674 : 105 , 002 , 133 , 045 , 144, 001 , 184
49680 : 232 , 134 , 046 , 032 , 089 , 166 , 203
49686 :076,116,164, 032, 121, 165, 184
49692 .-032,115,000,133,131,162,089
49698 : 000 , 1 34 , 073 , 032 , 253 , 1 94 , 208
49704 : 165 , 127 , 201 , 003 , 208 , 007 ,239
49710 : 162 , 002 , 134 , 073 , 032 , 253 , 190
49716 :194, 032, 115, 000, 240, 003, 124
49722 :032, 253, 174,032,061,195,037
49728 :165, 095, 166, 096, 133, 122, 073
49734 : 134, 123, 032, 215, 170, 208, 184
49740 :011, 200, 152, 024, 101, 122, 174
49746 : 133, 122, 144, 002, 230, 123, 068
49752 :032 , 201 , 197 , 240 , 005 , 032 ,027
49758 : 103 , 195 , 176 , 003 , 076 , 002 , 137
49764 : 194 , 132 , 085 , 230 , 085 , 164 , 222
49770 :085, 166, 049, 165, 050, 133, 242
49776 : 131, 177, 122, 240, 216, 221, 195
49782 : 000 , 002 , 208 , 237 , 2 32 , 200 , 2 29
49788 : 198, 131, 208 ,241, 136, 132, 146
49794 :011, 132, 151, 165, 073, 240, 134
49800 .-091,032,122,195,165,052,025
49806 : 056, 229, 050, 133, 158, 240, 240
49812 :040 , 200 , 240 , 202 , 177 , 122 , 105
49818 : 208, 249, 024, 152, 101, 158, 022
49824 : 201, 002, 144, 064, 201, 075, 079
49830 : 176, 060, 165, 158, 016, 002, 231
49836 :198, 131, 024, 101, 011, 133, 002
49842 : 151 , 176 , 005 , 032 , 180 , 195 , 149
49848 :240, 003, 032, 156, 195, 165, 207
49854 : 151, 056, 229, 052, 168, 200, 022
49860 : 165, 052, 240, 015, 133, 133, 166
49866 :166, 051, 189,000,002,145,243
49872 : 122, 232, 200, 198, 133, 208, 021
49878 : 245 , 024 , 165 , 045 , 101 , 158 , 184
49884 :133, 045, 165, 046, 101, 131, 073
55
2: Programming Aids
49890 : 133, 046, 165, 122 ,166, 123, 213
49896 : 133, 095, 134, 096, 166, 067, 155
49902 :165, 068, 032, 018, 196, 032, 237
49908 :090, 192, 240, 158, 164, 151, 215
49914 :076, 101, 194, 164, 122, 200, 083
49920 : 148,049, 169,000, 149,050,053
49926 : 185 , 000, 002 , 240 , 047, 197 , 165
49932 :131, 240, 005, 246, 050, 200, 116
49938 : 208 , 242 , 1 32 , 1 22 , 096 , 208 , 002
49944 : 033 , 141 , 003 , 002 , 142 , 004 , 093
49950 : 002, 140, 005, 002, 008, 104, 035
49956 : 141, 002, 002, 169, 164, 072, 074
49962 : 169, 116, 072, 056, 108, 022, 073
49968 :003 , 201 , 171 , 240, 004, 201 , 100
49974 : 045 , 208 , 001 , 096 , 076 , 2 17 , 185
49980 : 205 , 144 , 005 , 240 , 003 , 032 , 177
49986 :049, 195, 032, 107, 169, 032, 138
49992 :019, 166, 032, 121, 000, 240, 138
49998 : 011 , 032 , 049 , 195 , 032 , 115 , 000
50004 : 000 , 032 , 107 , 169 , 208 , 224 , 056
50010 : 165, 020, 005, 021, 208, 006, 003
50016 : 169, 255, 133, 020, 133, 021, 059
50022 : 096 , 032 , 201 , 197 , 133 , 067 , 060
50028 :032, 201, 197, 133, 068, 165, 136
50034 :020, 197, 067, 165, 021, 229, 045
50040 : 068, 096, 165, 122, 133, 034, 226
50046 : 165 , 123 , 133 , 035 , 165 , 045 , 024
50052 .-133,036,165,046,133,037,170
50058 :096, 165, 034, 197, 036, 208, 106
50064 :004, 165, 035, 197, 037, 096, 166
50070 : 230, 034, 208, 002, 230, 035, 121
50076 :164, 011, 200, 177, 034, 164, 138
50082 : 151, 200, 145, 034, 032, 139, 095
50088 : 195 , 208 , 235 , 096 , 165 , 036 , 079
50094 : 208 , 002 , 198 , 037 , 198 , 036 , 085
50100 : 164, 011, 177, 036, 164, 151, 115
50106 : 145, 036, 032, 139, 195, 208, 173
50112 : 235, 096, 201, 034, 208, 008, 206
50118 :072, 165, 015, 073, 128, 133, 016
50124 :015, 104, 096, 032, 107, 169, 215
50130 : 165, 021, 208, 004, 165, 020, 025
50136 :016, 002, 169, 127, 096, 076, 190
50142 : 2 17 , 205 , 208 , 251 , 032 , 232 , 087
50148 :195, 076, 116, 164, 032, 215, 002
50154 : 170, 133, 073, 166, 043, 165, 216
50160 : 044, 134 ,095 , 133 , 096 , 160 , 134
50166 :000, 177,095, 170,200, 177,041
50172 :095, 208, 003, 076, 115, 000, 237
50178 : 197, 138, 144, 235, 228, 137, 057
56
Programming Aids: 2
50184 : 144, 231, 200, 177, 095, 170, 001
50190 :200, 177,095,044, 160,000, 178
50196 : 132, 127, 132, 015, 032, 205, 151
50202 : 189 , 169 , 032 , 164, 1 27 , 041 , 236
50208 :127, 032, 210, 255, 032, 194, 114
50214 : 195, 169, 000, 133, 199, 200, 166
50220 : 036 , 073 , 016 , 023 , 166 , 096 , 198
50226 : 152, 056, 101,095,144,001,087
50232 : 232, 228, 138, 144, 010, 197, 237
50238 : 137 , 144 , 006 , 169 , 001 , 133 , 140
50244 :073, 133, 199, 177, 095, 240, 217
50250 :017, 016, 212, 201, 255, 240, 247
50256 :208, 036, 015, 048, 204, 132, 211
50262 : 127, 032, 122, 196, 048, 193 ,036
50268 :076, 215, 170, 096, 162, 160, 203
50274 : 160, 157, 134, 136, 132, 135, 184
50280 : 056, 233, 127, 170, 160, 000, 082
50286 : 202, 240, 238, 032, 147, 192, 137
50292 : 177, 135, 016, 249, 048, 244, 217
50298 :032, 096, 196, 200, 177, 135, 190
50304 : 048, 221, 032, 210, 255, 208, 078
50310 : 246, 032, 107, 169, 164,020, 104
50316 :166, 021, 152, 005, 021, 208, 201
50322 :002, 160, 100, 132,053, 134, 215
50328 :054 , 162 , 000 , 161 , 122 , 208 ,091
50334 :004, 169, 010, 208, 010, 032, 079
50340 : 253, 174, 032, 107, 169, 165, 040
50346 :020, 166, 021, 133, 051, 134, 183
50352 :052 ,032 , 142 , 166 , 032 , 201 ,033
50358 : 197 , 032 , 201 , 197 , 208 , 033 , 026
50364 : 032, 171, 197, 032, 201, 197, 250
50370 :032, 201, 197, 208,003,076, 143
50376 :002, 194, 032, 201, 197, 165, 223
50382 : 099, 145 , 122 , 032 , 201 , 197 , 234
50388 :165, 098, 145, 122, 032, 182, 188
50394 : 197, 240, 226, 032, 201, 197, 031
50400 : 032 , 201 , 197 , 032 , 201 , 197 , 060
50406 : 201 , 034 , 208 , 011 , 032 , 201 , 149
50412 :197, 240, 197, 201, 034, 208, 033
50418 : 247, 240, 238, 170, 240, 188, 029
50424 :016, 233, 162, 004, 221, 081, 197
50430 : 206 , 240 , 005 , 202 , 208 , 248 , 083
50436 :240, 221, 165, 122, 133, 059, 176
50442 : 165 , 1 23 , 133 , 060 , 032 , 115 , 126
50448 :000 ,176,211,032, 107 ,169,199
50454 :032, 080, 197, 165, 060, 133, 177
50460 : 123, 165, 059, 133, 122, 160, 022
50466 : 000 , 162 , 000 , 189 , 000 , 001 , 130
50472 :201, 048, 144, 017, 072, 032, 042
57
2: Programming Aids
50478 :115,000,144,003,032,129,21a
50484 : 197, 104, 160, 000, 145, 122, 012
50490 : 232, 208, 232, 032, 115, 000, 109
50496 :176, 008, 032, 144, 197, 032, 141
50502 : 121 , 000 , 144 , 248 , 201 , 044 , 060
50508 :240, 184, 208, 150, 032, 171, 037
50514 : 197, 032, 201, 197, 032, 201, 174
50520 : 197, 208, 008, 169, 255, 133, 034
50526 : 099 ,133, 098 , 048 , 014 , 032 , 006
50532 :201, 197, 197, 020, 208, 015, 170
50538 : 032 , 201 , 197 , 197 , 021 , 208 ,194
50544 : 011 , 032 , 209 , 189 ,169 ,032 , 242
50550 : 076, 210, 255, 032, 201, 197, 065
50556 :032, 182, 197, 240, 210, 032, 249
50562 : 161, 197, 230, 151,032, 180,057
50568 : 195 , 230 , 045 , 208 , 002 , 230 , 022
50574 :046 , 096 , 032 , 161 , 197 , 198 , 104
50580 : 151, 032, 156, 195, 165, 045, 124
50586 : 208 , 002 , 198 , 046 , 198 , 045 , 083
50592 :096, 032, 122, 195, 160, 000, 253
50598 : 132 , 011 , 132 , 151 , 096 , 165 , 085
50604 :053, 133, 099, 165, 054, 133, 041
50610 : 098 , 076 , 142 , 166 , 165 , 099 ,156
50616 :024 , 101 , 051 , 133 ,099, 165 , 245
50622 :098, 101, 052, 133, 098, 032, 192
50628 :201, 197, 208, 251, 096, 160, 029
50634 : 000, 230, 122, 208, 002, 230, 226
50640 : 123, 177, 122, 096, 076, 116, 150
50646 : 164, 208, 089, 165, 045, 133, 250
50652 :095, 165, 046, 133, 096, 165, 152
50658 : 095 , 197 , 047 , 165 , 096 , 2 29 , 031
50664 : 048, 176, 233, 160, 000, 132, 213
50670 : 036 , 200 , 177 , 095 , 010 , 102 , 090
50676 :036, 074, 153, 069, 000, 136, 200
50682 : 016 , 244 , 036 , 036 , 240 , 030 , 084
50688 :016, 051, 080, 089, 032, 112, 124
50694 : 198, 162, 037, 169, 061, 032, 153
50700 : 001 , 206 , 160 , 002 , 177 , 095 , 141
50706 : 072, 200, 177,095,168,104,066
50712 :032, 145, 179, 076, 044, 198, 186
50718 :032, 112, 198, 169, 061, 032, 122
50724 : 210, 255, 032, 133, 177, 032, 107
50730 : 162 , 187 ,032,215, 189 , 076 , 135
50736 :090, 198, 076, 217, 205, 032, 098
50742 :112, 198, 162,036, 169,061,024
50748 :032 ,001 , 206 , 169 ,034 , 032 , 022
50754 : 210, 255, 160, 004, 177, 095, 199
50760 : 133, 035, 136, 177, 095, 133, 013
50766 :034, 136, 177,095,032,036,076
58
Programming Aids: 2
50772 :171, 169, 034, 032, 210, 255, 187
50778 : 032, 215,170,032,090,192,053
50784 : 240 , 032 , 024 , 165 ,095 , 105 , 245
50790 : 007 , 133 , 095 , 144, 002 , 230 , 201
50796 :096, 076, 225, 197, 165, 069, 168
50802 : 032, 210, 255, 165, 070, 240, 062
50808 :003 , 032 , 210 , 255 , 096 , 208 , 156
50814 : 179, 032, 133, 198,076, 116,092
50820 : 164, 169, 004, 133, 035, 169, 038
50826 :000, 133, 034, 169, 004, 170,136
50832 :160, 255, 032, 186, 255, 032, 040
50838 : 192, 255, 032, 183,255,208,251
50844 : 107 , 162 , 004 , 032 , 201 , 255 , 149
50850 : 169, 025, 133, 037, 169, 013, 196
50856 :133, 015, 032, 210, 255, 169, 214
50862 :017, 174,024,208,224,021,074
50868 :208, 002, 169, 145 ,032, 210, 178
50874 : 255 , 160 , 000 , 177 , 034 , 041 , 085
50880 : 127, 170, 177, 034, 069, 015, 016
50886 :016, 011, 177,034,133,015,072
50892 :041, 128, 073, 146, 032, 210, 066
50898 : 255, 138, 201, 032, 176, 004, 248
50904 :009, 064, 208, 014, 201, 064, 008
50910 : 144, 010, 201, 096, 176, 004, 085
50916 : 009, 128, 208, 002, 073, 192, 072
50922 : 032, 210, 255, 200, 192, 040, 139
50928 :144, 203, 165, 034, 105, 039, 162
50934 : 133, 034, 144, 002, 230, 035, 056
50940 :198, 037, 208, 166, 169, 013, 019
50946 : 032, 210, 255, 032, 210, 255, 228
50952 .-169,004,032,195,255,076,227
50958 : 204, 255, 076, 217, 205, 076, 023
50964 : 002 , 194 , 208 , 248 , 165 , 043 , 112
50970 : 133, 135, 133, 034, 165, 044, 158
50976 :133, 136, 133, 035, 160, 003, 120
50982 : 177, 135, 145, 034, 136, 016, 169
50988 :249, 200, 132, 015, 177, 034, 083
50994 : 200, 017, 034, 240, 220, 160,153
51000 :004, 177, 135, 201, 058, 208, 071
51006 :006,200,177,135,240,048,100
51012 : 136, 177, 135, 201, 143, 240, 076
51018 : 041, 036, 015, 112, 004, 201, 227
51024 : 058 , 240 , 008 , 201 , 032 , 208 , 059
51030 : 009, 036, 015, 048, 005, 032, 231
51036 :147, 192, 208, 229, 170, 169, 183
51042 :064,005,015, 133,015, 138,212
51048 :145 , 034 , 200 , 201 , 000 , 240 , 156
51054 :046, 032, 194, 195, 208, 209, 226
51060 :136, 036, 015, 112, 013, 160, 076
59
2: Programming Aids
:000
:133
:177
:192
:005
:032
:170
:136
:024
:144
:199
:032
:164
:160
:076
:134
:036
:186
:032
:006
:246
:164
:180
:255
:240
:244
:200
:000
:132
:165
:133
:169
:243
:165
:215
:160
:255
:032
:030
:205
:165
:255
:160
:209
:170
:133
:255
:029
:174
,024,165,
,135,144,
,135,240,
,208,247,
,145,034,
,147,192,
,160,001,
,136,177,
,138,101,
,002,230,
,208,010,
,184,252,
,076,217,
,001,165,
,002,194,
,201,000,
,240,064,
,032,177,
,147,255,
,032,168,
,032,174,
,169,008,
,255,169,
,032,165,
,005,032,
,032,171,
,169,094,
,200,177,
,183,165,
,123,133,
, 186,165,
,096,133,
,165,186,
,185,032,
,170,169,
,003,132,
, 170,164,
,165,255,
,198,183,
,189,032,
,255,240,
,208,246,
,002,032,
,032,066,
,076,116,
,144,133,
,165,144,
,165,175,
,133,045,
135,105
002,230
005,032
036,015
200,016
208,135
177,034
034,133
034,133
035,076
120,162
088,076
205,208
044,145
160,000
240,032
169,008
255,169
177,122
255,200
255,076
133,186
111,032
255,201
210,255
255,076
133,134
122,208
122,133
188,169
134,208
185,032
032,180
150,255
000,133
183,032
144,208
164,144
208,237
063,171
005,032
032,215
090,192
246,032
164,169
147,032
041,191
133,046
032,089
,004,043
,136,140
,147,102
,080,150
,005,039
,152,250
,133,065
,135,147
,034,122
,036,187
,012,125
,116,168
,251,035
,043,246
,132,002
,201,252
,133,100
,111,130
,240,179
,208,081
,116,117
,032,172
,150,127
,013,157
,208,192
,128,154
,160,144
,251,218
,187,188
,008,058
,082,186
,213,112
,255,095
,032,115
,144,133
,165,239
,037,036
,208,032
,032,214
,032,024
,210,245
,170,214
,208,034
,215,156
,000,057
,213,170
,208,122
,165,093
,166,025
60
Programming Aids: 2
51360 : 032, 051, 165, 165, 134, 201, 140
51366 : 094, 240, 003, 076, 116, 164, 091
51372 :032, 142, 166, 076, 174, 167, 161
51378 : 076, 004, 247, 189, 240, 236, 146
51384 : 133, 122, 032, 195, 200, 133, 231
51390 : 1 23 , 032 , 040 , 203 , 096 , 181 , 097
51396 :217, 041, 003, 013, 136, 002, 096
51402 :096, 076, 129, 234, 165, 198, 076
51408 :240, 249, 165, 211, 201, 002, 252
51414 : 176 , 243 , 173 , 119 , 002 , 041 , 200
51420 : 127, 201, 017, 208, 234, 173, 156
51426 :001 , 008 , 013 , 002 , 008 , 240 , 242
51432 :226, 169, 000, 141 ,132,003,135
51438 : 141, 134, 003, 169, 039, 141, 097
51444 : 135, 003, 169, 024, 141, 133, 081
51450 :003, 032, 025, 203, 173, 119, 037
51456 :002, 048, 092, 166, 214, 224, 234
51462 : 024, 208, 083, 142, 131, 003, 085
51468 :142, 129, 003, 202, 048, 059, 083
51474 : 180 , 217 , 016 , 249 ,032 , 181 ,125
51480 :200, 176, 244, 032, 107, 169, 184
51486 : 230, 020, 208, 002, 230, 021, 229
51492 :032, 019, 166, 176, 016, 208, 141
51498 :014, 032, 049, 202, 032, 049, 164
51504 : 202, 169, 000, 133, 020, 133, 193
51510 :021, 240, 235,032,049, 202,065
51516 :206, 129, 003, 165, 217, 016, 028
51522 : 246, 032, 096, 202, 165,217,000
51528 :048, 003, 032, 049, 202, 162, 056
51534 :000, 189,120,002,157,119,153
51540 : 002, 232, 228, 198, 208, 245, 173
51546 : 198, 198,076 , 129, 234, 166 ,067
51552 : 214 , 208 , 249 , 142 , 129 , 003 , 01 7
51558 : 142, 131, 003, 202, 232, 224, 012
51564 : 025, 176, 222, 180, 217, 016, 176
51570 : 247, 032, 181, 200, 176, 242, 168
51576 :032 , 107 , 169 , 032 , 019 , 166 , 133
51582 : 165 , 095 , 166 , 096 ,197, 043 , 1 20
51588 :208, 018, 228,044,208,014,084
51594 : 032, 019, 202, 032, 019, 202* 132
51600 : 169, 255, 133, 020, 133, 021, 107
51606 : 208, 227, 133, 187, 202, 134, 217
51612 :188, 160, 255, 200, 177, 187, 043
51618 : 170, 208, 250, 200, 177, 187 ,074
51624 : 197, 095, 208, 246, 200, 177, 011
51630 : 187, 197, 096, 208, 239, 136, 213
51636 :152, 024, 101, 187, 133, 095, 104
51642 :165, 188, 105,000,133,096,105
51648 :165, 241, 048, 003, 032, 019, 188
61
2: Programming Aids
51654 :202,032,019,202,076,067,02s
51660 : 201 , 189 , 240 , 236 , 133 , 036 , 215
51666 : 032, 195, 200, 133, 037, 181, 220
51672 : 217, 009, 128, 096, 048, 002, 204
51678 :041, 127, 149, 217, 172, 134, 038
51684 :003, 136, 096, 032, 197, 200, 124
51690 : 133 , 035 , 200 , 177 , 034 , 145 , 190
51696 :036, 165, 035, 072, 041, 003, 080
51702 :009, 216, 133, 035, 165, 037, 073
51708 :072, 041, 003, 009, 216, 133, 214
51714 :037, 177, 034, 145, 036, 104, 023
51720 : 133, 037, 104, 133, 035, 204, 142
51726 : 135, 003, 144, 218, 096, 174, 016
51732 :133, 003, 232, 202, 032, 205,059
5 1738 : 201 , 180, 216 , 032 , 220, 201 , 052
51744 : 236 , 132 , 003 , 240 , 042 , 189 , 106
51750 : 239, 236, 133, 034, 181, 216, 053
51756 : 032, 231, 201, 176, 230, 174, 064
51762 : 132, 003, 202, 232, 032, 205, 088
51768 : 201 , 180 , 218 , 032 , 220 , 201 , 084
51774 :236, 133,003, 176,012, 189,043
51780 :241, 236, 133, 034, 181, 218, 087
51786 :032, 231, 201, 176,230,169,089
51792 :032, 200, 145, 036, 204, 135, 064
5 1798 : 003 , 144 , 248 , 181 , 2 17 , 009 , 1 20
51804 : 128 , 149 , 217 , 096 , 162 , 000 , 076
51810 : 134, 015, 142, 130, 003, 174, 184
51816 :129, 003, 189, 240, 236, 133, 010
51822 : 187 , 032 , 195 , 200 , 133 , 188 , 021
51828 :032, 076, 203, 133, 099, 032, 179
5 1834 : 079 , 203 , 032 , 1 36 , 192 , 162 , 1 58
51840 : 000 , 189 , 001 , 001 , 240 , 006 , 053
51846 :032, 188, 202, 232, 208, 245, 217
51852 :169, 032, 041, 127, 032, 188, 217
51858 : 202, 032, 079, 203, 008, 032, 190
51864 : 194 , 195 , 040 , 048 , 004 , 240 , 105
5 1870 : 069 , 208 , 2 39 , 201 , 255 , 240 , 090
51876 :235, 036, 015, 048, 231, 032, 249
51882 :096, 196, 200, 177, 135, 048, 254
51888 : 221, 132, 138, 032, 188, 202, 065
51894 : 164, 138, 208, 242, 169, 032, 111
51900 : 032 , 090 , 203 , 160 , 000 , 145 , 050
5 1906 : 187 , 165 , 188 , 072 , 041 , 003 , 082
51912 :009, 216, 133, 188, 173, 134, 029
51918 :002, 145, 187, 104, 133, 188, 197
51924 : 230, 187, 208, 002, 230, 188, 233
51930 : 238, 130, 003, 173, 130, 003, 127
51936 :201, 040, 240, 001, 096, 173, 207
51942 : 131, 003, 240, 017, 172, 129, 154
62
Programming Aids: 2
51948 :003, 192 ,024, 240, 039, 138 ,104
51954 :072, 206, 133, 003, 032, 049, 225
51960 : 202, 176, 008, 138, 072, 238, 058
51966 : 132, 003, 032, 019, 202, 032, 162
51972 :197, 200, 133, 188, 041, 127, 122
51978 : 149, 217, 189, 240, 236, 133, 150
51984 : 187 , 169 , 000 , 141 , 130 , 003 , 134
51990 :104, 170,096, 165,207,240,236
51996 :010, 160, 000, 132, 207, 164, 189
52002 : 211, 165,206,145,209,096,042
52008 : 160 , 000 , 140 , 130 , 003 , 240 , 201
52014 : 016 , 230 , 122 , 208, 002 , 230 , 086
52020 : 123,238,130,003,173,130,081
52026 : 003 , 201 , 040 , 176 , 232 , 177 , 1 19
52032 : 122, 201, 058, 176, 226, 201, 024
52038 :032, 240, 230,076, 179, 227,030
52044 :032, 079, 203, 230, 095, 208, 155
52050 :002, 230,096, 160,000, 177, 235
52056 :095, 096, 133, 137, 041, 127, 205
52062 : 201 , 032 , 008 , 041 , 063 , 040 ,223
52068 :176, 002, 009, 128, 036, 137, 076
52074 :016, 002, 009, 064, 096, 104, 141
52080 $104,032,215,170,032,204,101
52086 : 255, 169, 001, 032, 195, 255, 001
52092 : 169, 002, 032, 195, 255, 076, 085
52098 : 116, 164, 032, 207, 255, 032, 168
52104 : 207, 255, 240, 227, 165, 144, 094
52110 : 208 , 223 , 162 , 255 , 032 , 207 , 205
52116 :255, 133, 020, 032, 207, 255, 026
52122 : 133, 021, 232, 224, 078, 176, 250
52128 :008, 032, 207, 255, 157, 000, 051
52134 :002, 208, 243, 232, 232, 157, 216
52140 :000, 002, 232, 232, 232, 134, 236
52146 :011, 096, 032, 227, 204, 162, 142
52152 :002, 134, 152, 032, 198, 255, 189
521 58 : 032 , 132 , 203 , 032 , 017 , 205 , 043
52164 :032, 019, 166, 144, 068, 160, 017
52170 :001, 177,095,133,035,165,040
52176 :045, 133, 034, 165, 096, 133, 046
52182 :037, 165, 095, 136, 241, 095, 215
52188 :024, 101, 045, 133, 045, 133, 189
52194 : 036, 165, 046, 105, 255, 133 ,198
52200 : 046 , 229 , 096 , 170 , 056 , 165 , 226
52206 : 095 , 229 , 045 , 168 , 176 , 003 , 186
52212 : 232, 198, 037, 024, 101, 034, 102
52218 : 144, 003, 198, 035, 024, 177, 063
52224 :034 , 145 , 036 , 200 , 208 , 249 , 104
52230 : 230, 035, 230, 037, 202, 208, 180
52236 :242, 032, 089, 166, 032, 051, 112
63
2: Programming Aids
52242 : 165, 173,000,002,208,003,057
52248 :076 , 183 , 203 , 024 , 165 ,045 , 208
52254 : 133, 090, 101, 011, 133, 088, 074
52260 : 164, 046, 132, 091, 144, 001, 102
52266 : 200, 132, 089, 032, 184,163,074
52272 : 165, 020, 164, 021, 141, 254, 045
52278 :001, 140, 255, 001, 165, 049, 153
52284 : 164, 050, 133, 045, 132, 046, 118
52290 : 164, 011 , 136, 185 , 252 , 001 , 047
52296 :145, 095, 136, 016, 248, 032, 232
52302 :089, 166, 032, 051, 165, 076, 145
52308 :183, 203, 162, 001, 032, 198, 095
52314 : 255, 032, 207, 255, 133, 137, 085
52320 :032, 207, 255, 133, 138, 005, 098
52326 : 137, 201, 048, 240, 022, 166, 148
52332 : 137, 165, 138, 032, 001, 206, 019
52338 : 032, 207, 255, 032, 210, 255, 081
52344 : 201, 013, 208, 246, 104, 104, 228
52350 : 076, 116, 203, 032, 207, 255, 247
52356 :201, 013, 208, 249, 076, 204, 059
52362 : 255, 240, 068, 201, 036, 240, 154
52368 .-023,032,121,000,032,243,083
52374 : 188, 032, 247, 183, 165, 021, 218
52380 : 133, 194, 165, 020, 133, 193, 226
52386 : 032, 066, 205, 076, 116, 164, 053
52392 : 169, 000, 133, 098, 133, 099, 032
52398 : 169, 004, 133, 100, 032, 201, 045
52404 : 197, 240, 020, 032, 224, 205, 074
52410 : 162 , 004 , 006 , 099 , 038 , 098 , 081
52416 :202, 208, 249, 005, 099, 133, 064
52422 :099, 198, 100, 208, 231, 032, 042
52428 :209, 189, 076, 128, 200, 076, 058
52434 : 217, 205, 032, 207, 255, 133, 235
52440 : 194, 162, 000, 032, 059, 192, 087
52446 : 104, 104 , 076 , 053 , 205 , 032 ,028
52452 :148, 205, 032, 207, 255, 133, 184
52458 : 193 , 201 , 001 , 208 , 229 , 032 , 074
52464 : 207, 255, 133, 194, 076, 215, 040
52470 : 170 , 032 , 227 , 204 , 032 , 132 , 019
52476 :203, 032, 017, 205, 208, 248, 141
52482 : 104, 104, 160, 000, 185, 129, 172
52488 :163, 240, 045, 032, 210, 255, 185
52494 : 200 , 208 , 245 , 169 , 255 , 133 , 200
52500 :095, 169, 001, 133, 096, 133, 135
52506 :073, 166, 020, 165, 021, 032, 247
52512 :018, 196, 032, 090, 192, 240, 032
52518 : 219, 096, 032, 148, 205, 032, 002
52524 : 207, 255, 133, 193, 032, 207, 047
52530 : 255, 133, 194, 032, 059, 205, 160
64
H
n
H
52536 :076,116,203,166,193,165,207
52542 : 194 , 032 , 205 , 189 , 162 , 032 , 108
<— I 52548 :169,036,032,001,206,032,032
! * 52554 :235, 205, 076, 215, 170, 240, 191
52560 :022, 162, 254, 134, 193, 232, 053
52566 :134, 194, 032, 148, 205, 032, 063
R 52572 :207, 255, 032, 020, 206, 164, 208
52578 :144, 240, 246, 208, 206, 056, 174
52584 : 165 , 045 , 229 , 043 , 133 , 193 , 144
52590 : 165, 046, 229, 044, 133, 194, 153
52596 :032, 059, 205, 076, 116, 164, 000
52602 : 032, 152, 205, 032, 207, 255, 237
52608 :164, 144, 008, 032, 210, 255, 173
52614 : 040, 208, 008, 032, 090, 192, 192
52620 : 208, 239, 076, 004, 205, 076, 180
52626 : 1 13 , 203 , 169 , 000 , 240 , 002 , 105
52632 : 169, 002, 133, 134, 032, 231, 085
52638 : 255, 032, 087, 226, 166, 183, 083
52644 : 240, 051, 134, 015, 169, 001, 006
52650 : 133, 184, 169, 008, 133, 186, 215
52656 : 169, 015, 133, 185, 169, 000, 079
52662 : 133, 183,032,192,255,032,241
52668 :204, 255, 165, 015, 133, 183, 119
52674 : 169, 002, 133, 184, 169,008,091
52680 : 133, 186, 165, 134, 133, 185, 112
52686 : 032 , 192 , 255 , 032 ,086 , 204, 239
52692 : 162, 002, 076, 198, 255, 169, 050
52698 :255, 133,058,076,008, 175, 155
52704 : 201, 058, 008, 041, 015, 040, 075
52710 : 144, 002, 105, 008, 096, 165, 238
52716 :194, 032, 242, 205, 165, 193, 243
52722 :072, 074, 074, 074, 074, 032, 130
52728 :010, 206, 170, 104, 041, 015, 026
52734 :032, 010, 206, 072, 138, 032, 232
52740 : 210, 255, 104, 076, 210, 255, 090
52746 :024, 105 , 246 , 144, 002 , 105 ,124
52752 :006, 105, 058, 096, 230, 193, 192
— 52758 .-208,006,230,194,208,002,102
, ( 52764 :230, 190, 096, 173, 138, 002, 089
52770 : 073, 128, 141, 138, 002, 096, 100
52776 :032, 031, 206, 076, 116, 164, 153
T\ 52782 :167, 013, 078, 079, 084, 032, 243
; 1 52788 .-066,065,083,073,067,044,194
52794 : 032, 083, 084, 065, 082, 084, 232
— , 52800 :061, 000, 147, 066, 065, 083, 230
J | 52806 :073, 067, 045, 065, 073, 068, 205
52812 :032, 050, 013, 017, 000, 000, 188
52818 : 137, 138, 141, 167, 072, 069, 038
("J 52824 :076, 208, 065, 085, 084, 207, 045
Programming Aids: 2
65
2: Programming Aids
52830 : 066 , 082 , 069, 065 , 203 , 067 , 134
52836 :072, 065, 078, 071, 197, 068, 139
5 2842 : 069 , 076 , 069 , 084 , 197 , 070 , 159
52848 :076, 073, 083, 212, 068, 085, 197
52854 :077, 208, 070, 073, 078, 196, 052
52860 : 072, 069, 216, 067, 082, 212, 074
5 2866 : 075 , 073 , 076 , 204 , 077 , 069 , 192
52872 :082, 071, 197, 082, 069, 078, 203
52878 : 085 , 077 , 066 , 069 , 210 , 079 , 216
52884 :070, 198, 080, 065, 067, 203, 063
52890 : 082 , 069 , 065 , 196 , 083 , 067 , 204
52896 :082 , 079 , 076 , 204 , 083 , 084 , 000
5 2902 : 065 , 082 , 212 , 082 , 069 , 080 , 244
52908 :069, 065, 212, 190, 192, 175, 051
52914 : 222, 083, 073, 090, 197, 079, 154
52920 : 076, 196, 067, 079, 076, 196, 106
52926 : 000, 223, 195, 024, 193, 022, 079
52932 : 195 , 024 , 194 , 180 , 193 , 246 , 204
52938 : 204, 214, 197, 024, 194, 138, 149
52944 : 204, 124 , 198 , 070 , 192 , 179 , 151
52950 : 203 , 134, 196 , 182 , 199, 021 ,125
52956 :199, 121, 205, 086, 193, 039, 039
52962 .-205,039,206,208,199,208,011
52968 :199, 024, 200, 022, 200, 078, 187
52974 :205, 197, 199, 225, 252,000,036
52980 : 192, 156, 193, 206, 200, 083, 250
52986 :076, 049, 057, 048, 052, 056, 076
52992 1052,255,013,013,013,013,103
66
Programming Aids: 2
"Basic Aid" Clip-Out Quick Reference Card
Command and Syntax
AUTO line increment
BREAK
COXSGWstring/string/,line#
or
CHANGE "string"string",Une#
COLD
CRT
DELETE line# range
DUMP
¥lND/string/string/line#
or
FIND "string"string",line#
FLIST "filename"
HELP
HEX number
KILL
MERGE "filename"
OLD
OFF
READ "sequential filename"
RENUMBER
REPEAT
SCROLL
START "filename"
$ or @$
/filename
t filename
Function
Auto line numbering
Enter monitor
Search and replace string
Cold start
Screen print
Block delete
List variables and values
Find string
List to screen
Last line executed
Convert from decimal to
hexadecimal; vice versa
Disable BASIC Aid
Merge two programs
Reclaim NEWed programs
Restore normal IRQ vector
Read sequential file
Renumber program lines
Toggle repeat key function
Enable interrupt-driven
commands
Starting address of program
List directory
LOAD program
LOAD and RUN program
□
□
□
□
□
D
□
Jeff Young
Auto Line
Numbering
This short routine is a 'Auto Line Numbering" is a
handy, time-saving utility utility which automatically
for programmers. generates a line number for
the current BASIC program
statement you're entering. As written, the routine numbers programs
beginning with line 100 and increments by tens (100, 110, 120, and
so on). This can be easily modified.
How to Use the Program
Auto Line Numbering consists of a BASIC loader which places a
machine language subroutine into a free block of memory at location
49152 (SfCOOO). This area of memory is not used by BASIC, so the
program should be safe.
Type in the program and SAVE it. After LOADing, type RUN, press
RETURN, type NEW, press RETURN, then type SYS 49152. If you
wish to leave the program for any reason, just press RETURN immedi-
ately after you see a new line number. To return to the program,
type SYS 49160. This will continue generating line numbers from
where you left off.
Although the program will always begin numbering with 100 and
increment by tens, you can modify either of these if you wish. If you
want to begin with a number other than 100, determine the number
with which you want to start, then subtract ten. POKE this number
in low-byte/high-byte format into 251 and 252, then SYS 49160.
For example, if you wish to begin with line 1000, subtract ten.
The number you are now working with is 990. To determine low-
byte/high-byte, divide 990 by 256. The result, 3, is the number you
POKE into location 252— POKE 252,3. The remainder of the divi-
sion is 222. POKE 251,222. The low byte is location 251, and the
high byte, 252.
If you wished to begin the line numbering with 1000 then,
you'd enter:
POKE 251,222:POKE 252,3
SYS 49160
To change the increment from ten, POKE the desired number
into location 49179. If you want to increment by fives, for example,
you'd enter:
POKE 49179,5
69
2 : Programming Aids
This utility program can save you a lot of time when pro-
gramming, and it provides a neat, structured sequence for program
line numbers.
Auto Line Numbering
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
1 X=49152 :rem 203
2 READY :IFY=-1THEN4 : rem 199
3 P0KEX,Y:X=X+1:Z=Z+Y:G0T02 :rera 22
4 IFZ<> 12374THENPRINT "ERROR IN DATA STATEMENTS ": EN
D :rem 236
100 DATA169, 90, 133, 251, 169, 0,133, 252, 169, 19, 141, 2,
3,169,192,141,3,3,96,32,25 :rem 203
110 DATA 192 , 76, 134, 164, 24, 169, 10, 101 , 251 , 133, 251 , 1
44,2,230,252,165,251,133,99 :rem 246
120 DATA165, 252, 133, 98, 162, 144, 56, 32, 73, 188, 32, 221
,189,162,0,189,1,1,240,9,32 :rem 4
130 DATA210, 255, 157, 0,2, 232, 208, 242, 32, 18, 225, 201,
13,240,3,76,105,165,56,165 :rem 182
140 DATA251, 233, 20, 176, 2, 198, 252, 169, 131, 141, 2, 3,1
69,164,141,3,3,76,118,165,-1 :rem 36
70
Charles Kluepfel
Numeric Keypad
Turn your keyboard into a You could type in numbers
"Numeric Keypad" for more much faster and with fewer
efficient numeric input. The errors if the Commodore 64
program lets you toggle to had a numeric keypad. This
standard or numeric keypad. P^gum offers this handy
feature by redefining a set of
keys to represent numbers instead of letters.
When you run "Numeric Keypad," your computer will behave
normally until CTRL-N is pressed. The cursor disappears until you
press another key. Then the M, J, K, L, U, I, and O keys will be 0, 1,
2, 3, 4, 5, and 6. By using these along with the numeric keys 7, 8,
and 9, you have a numeric keypad. Pressing CTRL-N toggles the key-
board back into its normal mode (again causing the cursor to disappear
until you press a key). If you press RUN/STOP-RESTORE, however,
you won't be able to use the keypad option. You'll need to reRUN
the program to restore the feature.
\bu can put press-apply transfer numbers on the affected keys
to help you remember which number each key represents. You should
use very small ones, so they won't interfere with the normal identi-
fication of the keys. (Transfer letters and numbers are available at
many art supply stores.)
Use Numeric Keypad in a Program
You also can activate and deactivate the numeric keypad from a pro-
gram, in anticipation of numeric or nonnumeric input, by POKEing
location 50216 with 255 or respectively. The user can always over-
ride this with CTRL-N. (CTRL-N is never passed to the program, but
serves only as the toggle function.) Just don't POKE any value other
than or 255, because that would prevent you from toggling
with CTRL-N.
If you prefer that the keypad start out as activated, change the
next-to-last DATA item in line 520 from to 255.
Redefining the Keys
To redefine the 64 keys, we transfer the Kernal from ROM into RAM,
change it to intercept the M, J, K, L, U, I, and O keys, and convert
the data to the appropriate numbers.
Lines 3 and 4 POKE the machine language into an unused area
of memory from the DATA statements in lines 500-560.
Lines 10 and 20 transfer the BASIC interpreter and the Kernal
from ROM to RAM with the same addresses, so we can modify them.
71
2: Programming Aids
The Commodore 64 Programmer's Reference Guide, page 261,
states that turning off bit 1 in location 1 switches only the Kernal
addresses to RAM; actually it affects both the Kernal and BASIC
address ranges.
Line 25 merely signals that the transfer is complete (it takes
about a minute).
The Intercept Routine
Line 30 sets up the routine which intercepts keyboard characters.
It is put at the end of the routine that pulls a character from the
keyboard buffer.
Finally, line 40 activates the modified Kernal by turning off bit
1 of location 1 (changing the value in location 1 from 55 to 53).
Once this is done, the change has been made, and pressing CTRL-N
toggles between a numeric keypad and the normal usage of the M,
J, K, L, U, I, and O keys.
A Color Memory Bonus
A couple of bonuses have been included in lines 31 and 32. Line 31
changes the portion of the Kernal on newer 64s that puts the back-
ground color into the color memory for screen locations being
cleared. Instead of putting the background color there, it will now
put 1 (for white), so that if addresses 1024 to 2023 (decimal) are
POKEd, a character will appear. (See "Commodore 64 Video Update,"
COMPUTE!* Gazette, July 1983, page 44.)
POKEing 1000 locations as suggested there takes a few seconds
— not something to do for every PRINT of a screen clear.
Choose a Color
In the normal mode, printed characters will be light blue on a dark
blue background, while POKEd characters will be white. Change the
POKE to location 58587 in line 31 to some other number if you would
like a color different from white for POKEd screen characters. Of
course, if you have an older 64 which does not clear color memory
to the background color, leave out this patch (line 31).
Line 32 eliminates the printing of a question mark and space in
an INPUT statement prompt. This makes it possible to write:
100 INPUT "TITLE:";T$
and have the resulting screen look like
TITLEtCOMPUTE!
In any place where you really want the ? and the space, you
can put them inside the quotes.
72
Programming Aids: 2
Using this INPUT feature, and calling the keypad routine from
within your own program, you could create something like:
10 POKE 50216,255
20 INPUT "NUMBERS ";N
30 PRINT N
40 POKE 50216,0
50 INPUT "WORDS" ; N$
60 PRINT N$
As long as the keypad routine has been placed in memory, you
can activate and deactivate it by POKEing location 502 16 with 255
or respectively. Then, using the INPUT statement, you can enter
numbers or words. This makes the keypad routine even more versatile.
Numeric Keypad
For mistake-proof program entry, be sure to read "The Automatic Proofreader,"
Appendix C.
3 FORI=50176TO50261:READX:POKEI,X : rem 40
4 NEXT :rem 115
10 FORI=40960TO49151 : POKEI , PEEK ( I ) :NEXT :rem 142
20 FORI=57344T065535 : POKEI , PEEK ( I ) :NEXT :rem 151
25 PRINT "TRANSFERRED " : rem 120
30 POKE 58823, 76 :POKE58824,0:POKE58825, 196 : rem 70
31 P0KE58586,169:P0KE58587,l:P0KE58588,234:rem 134
32 PORI=44029TO44034 : POKEI, 234 :NEXT :rem 103
40 POKE 1,53 :rem 88
500 DATA201, 14, 240, 65, 44, 40, 196, 240, 28, 20
1, 85, 240, 40, 201 :rem 221
510 DATA73, 240, 40, 201, 79, 240, 40, 201, 74, 24
0, 16, 201, 75, 240 :rem 221
520 DATA16 , 201, 76, 240, 16, 201, 77, 240, 28, 88
, 24, 96, 0, 169 :rem 103
530 DATA 49, 208, 248, 169, 50, 208, 244, 169, 51,
208, 240, 169, 52, 208 : rem 163
540 DATA 236, 169, 53, 208, 232, 169, 54, 208, 228
, 169, 48, 208, 224, 169 :rem 224
550 DATA 255, 77, 40, 196, 141, 40, 196, 88, 165,
{SPACE} 198, 240, 252, 120, 76 : rem 117
560 DATA 180, 229 : rem 23
73
David W. Martin
One-Touch
Commands
You can put the normally Unlike most people,
unused function keys on the 64 computers excel at per-
to work with this programmer's forming boring, repetitive
utility. An entire commandcan tasks. What's more, time-
fee typed with a single keypress. consuming tasks which
You '11 quickly appreciate the ^ ^ ^ c ^
time saved with this technique I^^TZ^o^'
as you enter programs. £ cond ItomymakesS ense
to let computers handle the things they do best.
One of these jobs is the routine typing of frequently used com-
mands. During a session with your computer, how many times do
you type RUN, LIST, SAVE, or LOAD? Probably more times than you
think. If you're a hunt-and-peck typist new to typewriter-style key-
boards, this can be a major annoyance. Even if you're a fast touch-
typist, you probably stumble over such often-used commands as
POKE 53281,1:PRINT" {BLK} " (which sets up an easier-to-read white
screen background with contrasting black characters).
The utility presented here can free you from all that. It redefines
the special function keys (f 1 through f8 to the right of the keyboard)
so that a single keypress enters a whole command. The short while
it takes to type in this program can pay for itself many times over.
One-Touch Commands
Be sure to type the program carefully. As always, save it twice on tape
or disk before running it for the first time. The program is in the
familiar form of a BASIC loader— a BASIC program which includes
a machine language program encoded in DATA statements. A mistyped
number can "crash" the computer when the program is first run,
forcing you to switch it off, then on again to clear the machine. Saving
the program beforehand can prevent you from losing all your work.
Actually, this BASIC loader contains two machine language pro-
grams. Neither program consumes any memory normally used by
BASIC (see Programmer's Notes below). After activating the utility,
it erases the BASIC loader from memory and allows you to load your
own programs. The utility keeps working "in the background," so to
speak, until you turn off the computer or reset it by pressing RUN/
STOP-RESTORE.
74
Programming Aids: 2
The utility is very easy to use. First, enter and run the BASIC
loader. You'll see a screen prompt which asks:
Fl?
Now, type in whatever command you'd like to have available
at a stroke of the f 1 key. Then press RETURN. For instance, if you
answer the prompt by typing LIST and pressing RETURN, hitting
f 1 after the utility is activated will print the command LIST on
the screen.
There's a way to save even more keystrokes. If you answer the
prompt by typing the command followed by a back arrow — using
the back arrow key in the upper-left corner of the keyboard — the
utility will press RETURN for you, when activated. Otherwise, it's
up to you to hit RETURN when using each command. In other
words, answering the prompt like this:
Fl? LIST [Press RETURN]
means that when the utility is working, it will type the command
LIST on the screen for you, but you'll still have to press RETURN
yourself to actually execute the command. But if you answer the
prompt like this:
Fl? LIST <- [Press RETURN]
it means the utility, when working, will type LIST and press RETURN
for you when you hit the f 1 key. The back arrow makes the command
self-executing. Pressing the function key executes the command
instandy. Depending on the command, this may or may not be
desirable. For instance, you probably wouldn't want the command
NEW to execute instantly because it would be too easy to acciden-
tally wipe out a BASIC program. (In fact, you probably wouldn't
want to program a function key with NEW at all.)
You can also answer the prompt with more than one command.
An example might be:
Fl? LOAD «-RUN <- [Press RETURN]
which means f 1 will automatically load and run the next program
from tape.
After answering the Fl? prompt, the utility asks for F2, F3, and
so on through F8. After F8, the utility immediately activates itself
and erases the BASIC loader from memory.
The function keys are now programmed. They will remain so
until you shut off the computer or trigger a warm start by pressing
RUN/STOP-RESTORE.
75
2: Programming Aids
Programmer's Notes
The one-touch command utility consists of two machine language
programs tucked away in different parts of the Commodore 64 's
memory. The first part is in the cassette buffer, starting at memory
location 828 ($033C hexadecimal). This program asks for the key
definitions. Each time RETURN is pressed, it stores the ASCII values
of the characters into high memory.
Since the cassette buffer is used only temporarily, as you pro-
gram the function keys, you can load or save programs from or to
tape and not erase this routine. There may be problems, however, if
you're trying to use another machine language program which stores
data starting at location 49152. That's because this routine uses that
area for its second program (see below).
After entering f8, control jumps to the second program, stored
in high memory at location 49152 ($ C000 hex). This is a 4K block
of unused memory in the 64. The first two POKEs in the first line of
the BASIC loader fool EASIC into tWnking that memory ends at 53248.
To restore normal vectors, you can enter POKE 56,160:POKE 55,0.
The first machine language program also sets up an interrupt.
Every sixtieth of a second, the computer checks the second program
to see if a function key has been pressed. If so, the key's definition is
printed on the screen. If a back arrow was defined after the com-
mand, the program forces a RETURN to execute the command also.
One-Touch Commands
For mistake-proof program entry, besure toread "The Automatic Proofreader," ' Appendix C.
1 POKE56 , 208 : POKE55 , sF=0 :C=PEEK( 55 ) -120 : IFC<0THEN
C=C+256 :F=-1 : rem 84
2 D=PEEK(56)+F:POKE55,C:POKE56,D : rem 139
3 S=828: 1=146 :GOSUB100 : rem 11
10 DATA32, 198, 3, 165, 55, 133 ,251, 133, 253 ,165, 56, 133,
252,133,254,169 : rem 184
15 DATA49, 133, 167, 169, 133, 133, 168, 169, 13, 32, 210, 25
5,169,70,32,210 : rem 186
20 DATA255, 165, 167, 32, 210, 255, 169, 61, 32, 210, 255, 16
9,63,32,210,255 :rem 178
25 DATA169, 32, 32, 210, 255, 32, 207, 255, 72, 160, 0,165,1
68,145,55,104 : rem 76
30 DATA32, 198, 3, 201, 13, 240, 14, 201, 95, 208, 2, 169, 13,
145,55,32 :rem 119
35 DATA207, 255, 76, 124, 3, 230, 167, 165, 167, 41, 1,208,1
0,24,165,168 :rem 33
40 DATA105, 4, 133, 168, 76, 170, 3, 56, 165, 168, 233, 3, 133
,168,165,167 :rem 43
45 DATA201,57,144,163,120,169,L0,141,20,3,169,H0,1
41,21,3,88 :rem 215
76
Programming Aids: 2
50 DATA169, 0,133 ,167, 32, 68, 166, 76 ,116,164,166,55,2
08,2,198,56 :rem 8
55 DATA198,55,96 :rem 87
56 S=PEEK(55)+256*PEEK(56) :I=120:GOSUB100 : rem 76
57 SYS (828) : rem 94
58 END :rem 68
60 DATA165,167,240,59,160,0,177,251,32,L99,H0,176,
12,165,55,197 : rem 147
65 DATA251, 208, 21, 165, 56, 197, 252, 208, 15, 169, 0,133,
167,165,253,133 : rem 193
70 DATA251, 165, 254, 133, 252, 76, 49, 234, 166, 198, 177, 2
51,157,119,2,230 : rem 252
75 DATA198 , 32 , Llll ,H0 , 165 , 198 , 201 , 11 , 144 , 204, 230 , 1
67,76,49,234,165 : rem 28
80 DATA 2 15, 32, L99,H0, 176, 3, 76, 49, 234, 165, 8, 41, 1,20
8,247,160 :rem 197
85 DATA0,177,251,197,215,208,6,32,L111,H0,76,L6,H0
,32, Llll, H0 :rem 106
90 DATA76,L81,H0,201,133,144,6,201,141,176,2,56,96
,24,96,166 :rem 239
95 DATA251, 208, 2, 198, 252, 198, 251, 96, 0,0 :rem 188
100 F=0 : FORD=STOS+I : READA$ : IFASC ( A$ ) < 58THENA=VAL ( A
$) :GOTOH5 :rem 173
105 IFASC ( A$ )=76THENA=VAL( RIGHT$ ( A$ , LEN( A$ ) -1 ) )+PE
EK(55) :IFA>255THENA=A-256:F=1 : rem 73
110 IFASC ( A$ ) =72 THENA=VAL( RIGHT $ ( A$ , LEN( A$ ) -1 ) ) +PE
EK(56)+F:F=0 :rem 22
115 POKED, A: NEXT: RETURN : rem 10
77
David W. Martin
Dr. Video
The cursor control keys on While revising long pro-
your 64 already give you some rams or doing repeated
of the most powerful screen- numerical calculations in
editing capabilities of any home immediate mode, it's often
computer, but this utility adds useful to be able to clear a
even more: clear screen below P ort10 " of the screen dis-
the cursor, clear screen above whl e l ? avm * Jf rest
x , , „, „ ^ intact. It s also useful at
the cursor, and home the time§ tQ be abk tQ l<home „
cursor to the bottom left of the cursor to the lower left
the screen, all at machine of the screen inste ad of the
language speed. usua i upper-left position.
Although Commodore built excellent screen-editing features into
the 64, "Dr. Video" adds even more flexibility by giving you three
additional cursor control keys. A special technique allows Dr. Video
to function even while you are typing or running another program.
Since the program is written entirely in machine language, it doesn't
take up any of the memory normally used for BASIC programming.
The new cursor control features are assigned to three of the 64 's
function keys. The assignments are as follows:
f 1 Clear display to the top of the screen starting with the line
containing the cursor,
f 3 Clear display to the bottom of the screen starting with the
line containing the cursor,
f 5 Move the cursor to the lower-left corner of the screen.
How the Doctor Operates
Every V6o second your 64 stops whatever it is doing and takes some
time to read the keyboard and perform other housekeeping tasks.
These breaks are called interrupts, and the machine language pro-
gram which runs during this interrupt period is called the interrupt
service routine. When the microprocessor receives the interrupt
request (IRQ) signal, it looks at a pair of memory locations to find
the starting address (called the IRQ vector) of the interrupt service
routine to be executed. On the 64, the IRQ vector is contained in
locations 788 and 789, which normally point to address 59953, the
beginning of the standard IRQ service routine in ROM (unchanging
memory). However, since the IRQ vector is stored in RAM, changeable
memory, we can substitute the address of our own machine language
subroutine and add it to the normal interrupt service routine.
78
Programming Aids: 2
Like all interrupt-driven routines, Dr. Video continues to run
until you reset the computer (by hitting the RUN/STOP and RESTORE
combination, for example). It is not disabled by hitting just the STOP
key. After a reset, you can reactivate the new screen-editing keys by
typing SYS 49152.
Typing In the Program
Dr. Video is a machine language program which uses a BASIC loader
to POKE the data into memory and issue the SYS to start it running.
A checksum is calculated to assist in detecting typing errors in the
DATA statements, but since the loader program NEWs itself out of
the BASIC memory area, you should be careful to save a copy before
running for the first time.
Dr. Video
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
200 FORI=0TO148 : rem 111
210 READJ:POKE49152+I,J:X=X+J:NEXTI : rem 175
230 IFX<>17525THENPRINT"ERROR IN DATA":STOP
:rem 181
240 SYS49152:NEW : rem 190
300 DATA120, 169, 13, 141, 20, 3, 169, 192, 141, 21, 3, 88, 96
,165,197,41 :rem 236
310 DATA127, 201, 4, 208, 27, 169, 0,133, 25, 169, 4, 133, 26
,216,24,165 :rem 226
320 DATA209, 105, 40, 133, 27, 165, 210, 133, 28, 144, 2, 230
,28,24,144,46 : rem 59
330 DATA165, 197, 41, 127, 201, 5, 208, 19, 165, 209, 133, 25
,165,210,133,26 :rem 175
340 DATA169, 232, 133, 27, 169, 7, 133, 28, 24, 144, 19, 201,
6,208,67,169 : rem 45
350 DATA192, 133, 209, 169, 7, 133, 210, 169, 24, 133, 214, 2
4,144,44,216,56 : rem 180
360 DATA165, 27, 229, 25, 133, 29, 165, 28, 229, 26, 133, 30,
169,32,166,30 : rem 92
370 DATA240, 12, 160, 0,145, 25, 200, 208, 251, 230, 26, 202
,208,246,166,29 : rem 156
380 DATA240, 8, 160, 0,145, 25, 200, 202, 208, 250, 169, 0,1
33,211,169,32 : rem 54
390 DATA133,197,76,49,234 : rem 17
79
E. A. Cottrell
Step Lister
"Step Lister" is a timesaving As you're programming,
programming aid which lets you probably use the LIST
you look at your BASIC program command often. It's the
lines without repeatedly typing oni Y wa 7 y°" can turn the
LIST. It's short, and safe P a S es of y° ur program
from BASIC when il ' s in y° ur com P ut -
er's memory. But LIST can
be clumsy, for you have to either constantly type LIST and hit the
RUN/STOP key, or type LIST and a line number or range. You can
easily miss the line you want to examine. No matter what, you
have to type LIST a lot. "Step Lister" is a machine language wedge
(explained below) which allows you to step through a BASIC listing
one line at a time.
Type in and SAVE Step Lister. It's in the familiar form of a BASIC
loader which POKEs a machine language program into high memory
starting at location 49152 and issues a SYS command to run it. Since
even a single error in typing it in can lock up your computer, forcing
you to turn it off, then back on, to restore control, make sure you
save Step Lister before RUNning it. That way, you won't lose all
your typing.
RUN the program. It's now safe from BASIC. You can LOAD
another program and use Step Lister to look through it.
To see the first line of your program, just type:
@0.
(Entering any other number after the @ will start the listing at that
line. There should be no spaces between the @ and the line number,
and the @ must be on the left edge of the screen.)
Then, press any key and the next line will be displayed. Press the
space bar and hold it down, and the listing will continue scrolling
until the space bar is released.
If you wish to stop Step Lister, press RUN/STOP. The cursor
returns to the screen and you can edit a line or lines. Step Lister is still
available; enter the @ symbol and a line number to see another part
of the program.
What Is a Wedge?
To understand a wedge, you must first have some knowledge of how
BASIC works. When you press RETURN, one of two things happens.
If the entered line has a number as the first character, the computer
assumes that a BASIC line is being entered. This line is then converted
to BASIC tokens and put in its proper place in memory. (Tokens
80
Programming Aids: 2
are single-byte symbols which represent BASIC commands. To save
space and time, the computer stores PRINT, for example, as 153 )
No interpretation of the characters following the line number is
made until the program is run. If the first character is not numeric,
the line is tokenized and placed in the BASIC input buffer at locations
512-600 ($0200-80258). The interpreter then calls the CHRGET
subroutine to get the characters from the buffer and return them
for interpretation.
To implement a wedge, the CHRGET subroutine located at
115- 138 ($73-88A) must be altered to go to your machine language
program before returning to the interpreter. At the entry point of
the wedge, a check is made to see if the special character (in this case,
@) has been entered. If it has, the special routine is executed. Other-
wise, the character is sent to the interpreter for normal BASIC
interpretation and execution.
Using ROM Routines
Step Lister uses many of the subroutines which are part of the BASIC
ROM in the 64. Analyzing some of the subroutines already in the
machine can prove useful.
The wedge can be a powerful tool. If you decide to write a
wedge program of your own, heed one word of caution: Do not try
to alter the CHRGET subroutine with BASIC. You will be changing
the way BASIC gets its instructions in the middle of a BASIC program,
and this will crash your computer.
Step Lister
For mistake-proof program entry, be sure to read "The Automatic Proofreader" AppendixC.
10 TM=49152 :rem 68
20 FOR I = TM TO TM + 241 : rem 118
30 READ A: POKE I, A: CHK = CHK + A: NEXT I :rem 48
40 X = 828: FOR I = X TO X + 23 :rem 37
50 READ A: POKE I, A: CHK = CHK + A: NEXT I :rem 50
60 IF CHK <> 32456 THEN PRINT "DATA ERROR": END
:rem 254
70 SYS49152 :rem 107
100 DATA162, 0,189, 60, 3, 149 ,115,232,224,23,208,246,
0,201,64,240,22,201 : rem 84
120 DATA58, 176, 10, 201, 32, 240, 11, 56, 233, 48, 56, 233, 2
08,96,76,116,164,234 : rem 169
140 DATA76, 115, 0,160, 0,185, 0,2, 201, 64, 208, 243, 200,
185,0,2,201,0,240,9,201 :rem 1
160 DATA45, 208, 244, 169, 171, 153, 0,2, 169, 1,133, 122,1
60,1,24,185,0,2,32,107 : rem 238
180 DATA169, 32, 19, 166, 160, 0,32, 121, 0,32, 107, 169, 16
5,20,5,21,208,6,169 :rem 106
81
2: Programming Aids
200 DATA255, 133, 20, 133, 21, 160, 1,132, 198, 160, 1,132,
15,177,95,240,175,32 :rem 144
220 DATA44, 168, 32, 215, 170, 134, 25, 132, 26, 173, 198,0,
240,251,169,0,141,198 : rem 214
230 DATA0, 166, 25, 164, 26, 200, 177, 95, 170, 200, 177, 95,
197,21,208,4,228,20 : rem 120
250 DATA240, 2, 176, 44, 132, 73, 32, 205, 189, 169, 32, 164,
73,41,127,32,71,171 : rem 120
270 DATA201, 34, 208, 6, 165, 15, 73, 255, 133, 15, 200, 240,
17,177,95,208,16,168 :rem 171
290 DATA177, 95, 170, 200, 177, 95, 134, 95, 133, 96, 208, 16
3,108,6,3,16,218,201 :rem 188
310 DATA255, 240, 214, 36, 15, 48, 210, 56, 233, 127, 170, 13
2,73,160,255,202,240,8 :rem 251
320 DATA200, 185, 158, 160, 16, 250, 48, 245, 200, 185, 158,
160,48,181,32,71,171,208 :rem 112
350 DATA245, 0,230, 122, 208, 2, 230, 123, 173, 0,2, 201, 58
,240,10,201,32,240,239 : rem 214
370 DATA76,13,192,234,234,234,96 :rem 99
82
Charles Brannon
Foolproof INPUT
Machine language routines, Problems with INPUT
even short ones, can perform You are probably familiar
some impressive functions. with some of the problems
Overcoming some of the prob- with the INPUT statement.
lems of the INPUT statement is First > il wil1 not properly
relatively easy in machine lan- handle input with commas
gua^rout^^ ^^SSSt
BASIC'S own INPUT routine com ^ uter would accept
and can be added to your own only the word « First » and
program. Since it's in the form ignore the rest of the line
of a BASIC loader, you don't me computer warns you
need any special knowledge w ith ?EXTRA IGNORED).
of machine language. This is because the comma
is used to separate multiple
INPUTs on the same line, as in this example:
INPUT "ENTER NAME: FIRST,LAST";A$,B$
The colon, too, triggers an PEXTRA IGNORED message. Yet it
cannot be used to separate INPUT items, so it appears to be some
kind of a bug (error) in the BASIC language itself.
You can get around these problems somewhat, but they become
especially annoying when you are trying to read a file on tape or disk
containing these characters. In a mailing list program, for instance,
you need commas for address fields such as "Greensboro, NC, 27403" .
There are other difficulties with the INPUT statement. Quota-
tion marks are not handled correctly. Leading and trailing spaces are
stripped away. INPUT also allows people to use all the cursor and
color control keys. Theoretically, you can place the cursor anywhere
on the screen where there is something you want to INPUT, and press
RETURN. In effect, this is what happens when you edit a program
(the same INPUT routine is used by both the system and BASIC). But
it just makes no sense to allow cursor moves all over the screen
when you simply want the user to answer a question. If the user
accidentally presses a cursor key and then tries to move the cursor
back, the entire line, including any prompts, is read.
This can also be a problem when you have carefully laid out a
screen format with blanks or boxes into which the user is supposed
to enter information. You have no way to control how many charac-
ters the user can type, so if your blank space is only ten characters
long, there is nothing to prevent someone from typing more. Not
83
2: Programming Aids
only that, but with the standard INPUT routine, someone can move
the cursor out of the box you want them to use, clear the screen
entirely, or otherwise destroy your carefully planned format.
Improving on INPUT
What we need, then, is a new INPUT routine that will not allow
cursor moves. The DEL key should still let the user delete characters
to make corrections, however. Additionally, the ideal INPUT routine
should let your program limit the number of characters typed, yet
allow commas and colons.
The usual solution is to write your own INPUT routine using
the GET statement, which fetches one key at a time from the key-
board. With such a simple statement as GET, however, you have to
reinvent the wheel anytime you need such a protected INPUT rou-
tine. And it certainly isn't as easy to use as a simple INPUT statement.
Well, I certainly wouldn't bring such gloom to the scene without
a solution. The accompanying program is the key. It's a machine
language routine that replaces the standard Commodore INPUT with
a protected INPUT like the one described above. The beauty of it is
that after you GOSUB 60000, all INPUT (and INPUT#) statements are
redefined. You don't have to understand how the machine language
works in order to use it, and you don't have to rewrite any existing
programs, other than to insert the GOSUB. You still have all the flexi-
bility of the standard INPUT statement. Just add the subroutine to
the end of your program.
The machine language program has a couple of niceties. After
you GOSUB 60000, you can change the maximum number of charac-
ters allowed by POKEing memory location 251 with the length (don't
POKE with zero, or more than 88). The cursor is an underline by
default, but you can change the character used by POKEing its ASCII
value into memory location 2. For example, to change the cursor
into an asterisk, enter:
POKE2,ASC("*")
or
POKE 2,42
When you use the routine to INPUT data from files, just remem-
ber that it strips away all control characters, from CHR$(0) to CHRjf (31 )
and CHR»(128) to CHR$(159). This includes all special codes such as
cursor controls, function keys, color codes, etc. You'll rarely write
these to a standard data file, anyway.
84
Programming Aids: 2
Cautions
Curiously, "Foolproof INPUT" does not work properly in direct
mode. To make BASIC accept commas and colons, an invisible quote
is added to the start of each line that is input. Naturally, direct mode
doesn't like statements such as RUN or LIST. If you want the special
INPUT routine out of your way, just press RUN/STOP-RESTORE.
The invisible quote also prevents you from using something like
INPUT A. Only string variables work with this routine; use INPUT
AS5 instead. If you want, you can include a line such as:
INPUT A$:A = VAL(A$)
instead of INPUT A.
To display the contents of A$ (or any other string variable set
with INPUT using this routine), PRINT it from within a program.
For instance:
10 GOSUB 60000: INPUT A$
20 PRINT A$ : END
would PRINT the contents of A$ . If you INPUT something, then use
the PRINT statement in direct mode, you'll get a SYNTAX ERROR.
Pressing RUN/STOP-RESTORE before printing, however, displays the
contents of the string variable correctly.
Foolproof INPUT
For mistake-proof program entry, besuretoread "The Automatic Proofreader," Appendix C.
60000
IFPEEK(830)=133THEN60020
:rem
145
60010
FORI=
=8 28T0983 : READA : POKEI
, A : NEXT
: rem
124
60020
SYS 8 28: RETURN
: rem
179
60030
DATA
169,000,133,252,169,
080
: rem
135
60040
DATA
133,251,169,
164,133,
002
: rem
131
60050
DATA
169,083,141,
036,003,
169
: rem
142
60060
DATA
003,141,037,
003,096,
152
:rem
127
60070
DATA
072,138,072,
165,252,
208
:rem
144
60080
DATA
007,032,116,
003,169,
000
:rem
123
60090
DATA
133,253,166,
253,189,
000
:rem
143
60100
DATA
002,133,254,
198,252,
230
: rem
129
60110
DATA
253,104,170,
104,168,
165
: rem
133
60120
DATA
254,096,160,
000,169,
034
: rem
135
60130
DATA
141,000,002,
132,252,
165
:rem
115
60140
DATA
002,032,210,
255,169,157
: rem
132
60150
DATA
032,210,255,
032,228,
255
: rem
131
60160
DATA
240,251,164,
252,133,
254
: rem
135
60170
DATA
169,032,032,
210,255,
169
: rem
141
60180
DATA
157,032,210,
255,165,
254
: rem
141
60190
DATA
201,013,240,
043,201,
020
: rem
111
60200
DATA
208,013,192,
000,240,
211
: rem
114
85
2: Programming Aids
60210 DATA 136,169,157,032,210,255 :rem 138
60220 DATA 076,123,003,041,127,201 : rem 120
60230 DATA 032,144,196,196,251,240 : rem 141
60240 DATA 192,165,254,153,001,002 :rem 129
60250 DATA 032,210,255,169,000,133 :rem 126
60260 DATA 212,200,076,123,003,230 :rem 118.
60270 DATA 252,230,252,153,001,002 :rem 120
60280 DATA 169,032,032,210,255,096 : rem 142
86
John Krause and David W. Martin
64 Searcher
"64 Searcher" is a time-saving When working on a long
utility that searches through your BASIC program, it pays to
BASIC program and locates any p!* n ahead. But it seems
character or string of characters. that no matter how hard ,
you try, you can t keep track
of everything in your program. Can I use H to store the high score,
or is that variable already being used for something else? Where is
this subroutine called from? You probably end up searching for a
number or word hidden among scores of program lines.
"64 Searcher" allows you to spend less time searching and more
time programming. Simply give it the string of characters to search
for, and it tells you the numbers of all lines in which the string appears.
It can search a hundred lines faster than it takes you to search one.
It's fast because it's machine language. But you don't have to know
machine language to use it.
Searching
Enter the program carefully and save it on tape or disk before ruiining
it for the first time. In the form of a BASIC loader and a series of DATA
statements, the program must be entered exactly as it appears.
By using "The Automatic Proofreader" in Appendix C, you should
be able to type it in correctly the first time. If there's even one
error, the computer may lock up (not respond to keypresses). You'll
have to turn it off, then on again, to regain control. If you've saved
the program, you can load it again and begin looking for the
typing mistake.
To use 64 Searcher, load and run it, then load your BASIC
program. 64 Searcher doesn't use any BASIC memory, so you can
work on your program normally. To initiate a search, type followed
by the string you want to find. The string must be enclosed within
either slashes or quotes. Hit the RETURN key and the string is stored
in your program as line 0. If your program already has a line 0,
you'll have to change that line number because the string must be the
first line in the program.
Type SYS49152 and press RETURN. Instantly you'll see numbers
appear on the screen. These are the line numbers that contain the
string you specified. If no match is found, no numbers will be printed.
If the string occurs more than once in a line, the line number is
printed only once.
Once you're done searching through a BASIC program, remem-
ber to delete line before saving or running it.
87
2: Programming Aids
Quotes and Slashes
Because BASIC commands are stored differently than other characters
in a program, there are two ways of specifying the search string. If
the string is enclosed within slashes (/), BASIC commands are recog-
nized as such. If the string is within quotes (""), however, it will be
treated as a literal string of characters.
For example, to find the BASIC statement AND, line should be:
/and/
After entering SYS49152, 64 Searcher will find the AND in this line:
10 IF X=l AND Y=2 THEN 50
but not in this line:
20 PRINT "THIS AND THAT"
To find the AND in line 20 above, you'd use quotes instead of slashes.
64 Searcher is an excellent debugging aid, especially for long pro-
grams, and will be a valuable addition to your toolbox of machine
language utilities.
64 Searcher
For mistake-proof program entry, be sure to read "The Automatic Proofreader,' 'Appendix C.
1 FORI =49 1 52T049255: READ J : K=K+ J : POKEI , J : NEXT
: rem 66
20 I FK <> 1 6 30 2THENPRINT " ERROR IN DATA STATEMENTS ": S
TOP :rem 117
30 PRINT"{CLR}SYS49152 TO SEARCH" : rem 36
100 DATA169, 1,133, 251, 169, 8, 133, 252, 160, 0,177, 251,
56,229,251,56 :rem 80
110 DATA233, 5, 141, 104, 192, 233, 2, 141, 105, 192, 160,0,
177,251,170,200 :rem 142
120 DATA177, 251, 240, 67, 133, 252, 134, 251, 160, 0,177, 2
51,56,229,251,170 : rem 17
130 DATA202, 134, 2, 198, 2, 165, 2, 205, 104, 192, 48, 222,1
33,253,173,105 : rem 110
140 DATA192, 133, 254, 164, 253, 177, 251, 164, 254, 217, 5,
8,208,229,198,253 :rem 45
150 DATA198, 254, 208 , 239 , 160 , 2 , 177 , 251 , 170 , 200, 177 ,
251,32,205,189,169 : rem 88
160 DATA32,32,210,255,76,26,192,96 : rem 190
88
Dan Carmichael
The Four-Speed
Brake
Not only does this machine One small inconvenience
language routine vary the speed of programming with the
of your listings, but it can Commodore 64 (if you don't
also select the speed at which have aprinter) is the limita-
your BASIC programs execute. tion of being able to display
And it doesn't use any of your re ! atlvel y sma11 sec "
„ " , ' j jj tions of your programs on
BASIC programming memory. ^ ^ at £ ne 8 time If
you have a large BASIC program, listings can be hard to follow. Even
slowing down the LIST command with the CTRL key isn't much
help at times; the BASIC lines still pass by at a reasonably fast rate,
and because of the way the lines "jump," they can be hard to follow.
The short program that follows will help slow things down for
you. It's a "Four-Speed Brake" that lets you vary the speed of your
listings from reasonably slow to a complete stop. The program is writ-
ten in machine language, and normally sits undisturbed in an area of
available memory called the cassette buffer. Once it is POKEd into
memory, it uses none of your available BASIC programming memory.
How to Use the Program
First, load your BASIC program into the computer, then either append
this program to it, or type it in after your program. Before running
the program for the first time, verify it carefully, and save it to tape
or disk. An error in this (or any) machine language program can
cause your system to crash, forcing you to turn your computer off
and then on to reset. After verification, type RUN 60000 and press
RETURN to POKE the machine language program into the cassette
buffer. Then type SYS828 and press RETURN. The Four-Speed Brake
is now running.
The program is controlled by the special function keys. The chart
illustrates what the function keys do.
To stop Four-Speed Brake, press RUN/STOP-RESTORE; to restart,
enter SYS828.
After the Four-Speed Brake has been successfully POKEd into
memory and tested, you may, if you wish, delete lines 60000-60040.
Also, the CTRL key will still work as it normally does in slowing
down your listings, and might be considered a "fifth speed," a little
faster than the f 1 key.
89
2: Programming Aids
The Four-Speed Brake also has another important benefit. It will
slow down or stop the running of your BASIC program just as it
slows the LIST command. This can be a very useful tool for debug-
ging your BASIC program. To do this, use the Four-Speed Brake in
the same manner as you would for the LIST command; enter SYS828,
then RUN your program. The function keys will slow down or stop
your BASIC program.
Special Function Keys
fl
fastest speed
f3
medium speed
f5
slowest speed
f7
complete stop
Words of Caution
First, this program runs in the cassette buffer, and as is true with all
programs in this buffer, you cannot use the tape cassette while this
program is running. Second, because of the way the computer out-
puts the lines while listing programs, you will encounter a glitch
every now and then. It will appear as if one line repeats itself. If you
continue to hold down the function key and let the screen scroll, it
will take care of itself. You can observe how this happens if you list
a program while holding down the f 5 key.
If you're a machine language programmer, the Four-Speed Brake
will also work, both in listing and running your ML programs. To
use, enter SYS828, then SYSXXX into your ML monitor as usual, or
SYSXXX into your machine language program. However, a word of
caution is needed here. The Four-Speed Brake uses all three registers
(A, X, and Y), so you'll have to be careful when using these registers
in your own program.
Four-Speed Brake
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
60000 FORA=828T0894 : READB : POKEA, B : NEXT : END : rem 127
60010 DATA120 , 169 , 73 , 141 , 20 , 3 , 169 , 3 , 141 , 21 , 3 , 88 , 96
,162,0,160,0,165,197,201 :rem 91
60020 DATA4, 208 , 10, 232 , 208 , 253 , 200 , 192 , 48 , 208 , 248 ,
160,0,201,5,208,6,232,208 : rem 134
60030 DATA253, 200, 208, 250, 201 ,6, 208,8, 232, 234, 234,
208,251,200,208,248,32 :rem 245
60040 DATA1 59 , 255 , 165 , 197 , 201 , 3 , 240 , 247 , 76 , 49 , 234
:rem 176
90
n
n
n
n
n
Todd Heimarck
ASCII/POKE
Printer
The computer does the work Reference Tables
for you in this short routine, Chances are, PRlNTing to
which automatically calculates the screen was one of the
ASCII and POKE values. A handy fi»t thin 8 s you learned to
programming utility, there's even do in BASIC - You probably
a BASIC-machine language com- lear " ed how to contro1
parison included. A disassembly ****** computer prints
* . . , ,. . < by putting cursor com-
of the code is also listed. ^^^sx^othy
using SPC and TAB commands. The PRINT command is common,
primarily because it is so easy to use. But in certain situations, you
may need to find out a character's ASCII number. And sometimes it
is quicker to simply POKE a character onto the screen.
But before you can POKE, you have to know the character num-
ber. Let's put a row of hearts at the top of the screen. So we need to
POKE abunch of 8Ts. Wait, those are solid circles. What's the number
for hearts? I know that list is somewhere.
If you use POKEs or ASCII values in programming, you know
how annoying it is to flip back and forth through the reference
book, losing time and patience. Even worse, you could lose the book
and end up typing the character and PEEKing screen memory to
get the POKE value.
Let the Computer Do the Work
Your computer already knows the POKE values and ASCII numbers,
so why not let it do the work?
This short machine language program, "ASCII/POKE Printer,"
does not use any BASIC memory. Its 52 bytes remain in the cassette
buffer, ready to convert letters and graphics characters to POKE and
ASCII numbers whenever you want.
Note that if you write a program that POKEs any of the address
locations of the cassette buffer (828-1019), you may lose ASCII/POKE
Printer. Also, if you use a cassette player for SAVEs, LOADs, or tape
files, you will erase the machine language program. Fortunately, it is
entirely relocatable, so if you want to use the cassette buffer, you
can change line 10 to move it to another part of memory. On the 64,
it is usually safe to use any of the memory locations from 49152
to 53247.
91
2: Programming Aids
LOADing and Using the Program
Type in ASCII/POKE Printer. Make sure the DATA statements are
exactly as printed. SAVE it to tape or disk and VERIFY (if you have a
cassette drive). RUN the program and type NEW. The program is
now in your cassette buffer. BASIC memory was cleared when you
typed NEW, but it did not touch the cassette buffer.
Anytime you want to use ASCII/POKE Printer, type SYS 828. The
computer will wait for you to type a character and then display that
character in the upper-left corner with the ASCII value to the right
and the POKE value below. Type another character and you get two
new values.
To exit (back to BASIC), hold down SHIFT and press RETURN.
This returns you to your program. SYS 828 will send you back to
ASCII/POKE Printer. You can toggle back and forth as the need arises.
Special Cases
There are some ASCII numbers that have no equivalent POKE. For
example, adding CHR$(13) to a string will force a RETURN after the
string is printed. But ASCII 13 cannot be POKEd to the screen (what
would a RETURN look like?). ASCII/POKE Printer will give you the
correct ASCII numbers, but for certain characters, like RETURN, it
will print a blank space and list a POKE of 32 (which is the number
for a blank space). In the case of function keys, CLR/HOME, INST/DEL,
and color commands, it will print a reverse video character, as if in
quote mode, and the correct ASCII number. But the POKE number
will be wrong. Keys that perform a function — clearing the screen,
for example — are not characters that can be POKEd to the screen.
Also note that you cannot get values for reverse video characters,
which do not have separate ASCII numbers. To program a reverse
character, precede it with a CHR$(18). To POKE a reverse video
character, add 128 to the POKE value of the regular character.
This machine language utility will be most helpful when you are
writing BASIC programs. By letting the computer tell you ASCII and
POKE values, you can really save time. The program was written to
be short and simple, but if you are familiar with machine language,
you could modify it to do much more.
Machine Language Vs. BASIC
This utility was originally written to avoid the problems of trying
to figure out the ASCII and screen codes. The Commodore 64
Programmer's Reference Guide contains the ASCII and screen codes,
92
Programming Aids: 2
but why look in the book when the computer already knows the
numbers? Let the computer do the work.
Writing the machine language routine was fairly easy, because
once again the computer can do the work. There are a number of
useful built-in ROM routines. Call the routines a few times and you
have the answer.
The first routine is GETIN. When you jump to this subroutine
(JSR $FFE4), it checks to see if a key has been pressed. If so, the
ASCII value of the key is put into the accumulator. If not; a zero is put
in the accumulator. Then it returns from the subroutine.
Another useful Kernal routine is CHROUT. When you JSR $FFD2,
the computer checks the value in the accumulator. The number is
translated from ASCII to a character and it is printed on the screen
(wherever the cursor happens to be at the time).
The final routine is at $BDCD. Among other things, it's used by
BASIC'S LIST routine to print line numbers. It takes the number in
the accumulator (the most significant byte or MSB) and multiplies it
by 256. Then the number in the X register (the least significant byte,
or LSB) is added. The result is converted into ASCII numbers and
printed on the screen. For example, if you load the accumulator
with number two and put 88 into X, JSR $BDCD calculates
2 * 256 + 88 = 600 and prints CHR$(54) + CHR$(48) + CHR$(48).
In other words, it prints the characters for the number 600.
The disassembly of the object code is listed as Program 2 at the
end of this article.
Here's a line-by-line explanation of the disassembly:
Line Function
033C Check to see if a key has been pressed.
03 3F If not, go back to 033C. If so, the accumulator holds the ASCII value
and the program continues.
0341 Save the value in X.
0342 Compare A to the number $8D (the ASCII for shifted return, to
exit to BASIC).
0344 If not equal (to $8D), continue at 0347.
0346 A does equal SHIFT-RETURN, return to BASIC.
0347 Put $93 into the accumulator (ASCII for clear screen).
0349 Print it.
034C Load A with $FF (255)
034E Store it in the quote flag (which turns on quote mode). Now if
you push the clear screen key, you will see a reverse heart.
0350 Transfer the number in X back to A.
0351 Print the character.
0354 Load A with $20 (ASCII for a blank space).
0356 Print it.
93
2: Programming Aids
0359 Load A with $00 (the MSB of the number to print in the
HEXDECPRNT routine).
035B Do the HEXDECPRNT — print the ASCII value (MSB in A is always
zero and LSB in X was transferred up at $0341).
035E Load A with $0D (ASCII for carriage return).
0360 Print it. Cursor position is now at the beginning of the second
screen line.
0363 Load A with zero (for HEXDECPRNT) again.
0365 Store A in the quote flag; turn off quote mode.
0367 Load X with the screen code of $0400 (1024). In other words,
X = PEEK(1024).
036A Go to HEXDECPRNT, to print the screen code.
036D Increment X (or X = X + 1).
036E If X is not equal to zero, branch back to the start. Because this line
is a branch (which is relative), the routine can be moved to other
memory locations. If it were aJMP, it would not be relocatable.
The program could be written completely in BASIC and would
look like:
828 GET G$:A=ASC(G$+CHR$(0)): REM START
831 IF G$="" THEN 828
833 X=A
834 IF G$=CHR$(141) THEN EQ=1
836 IF EQOl THEN 839
838 RETURN
839 A=147
841 PRINT CHR$(A);
844 A=255
846 POKE 212, A
848 A=X
850 PRINT CHR$(A);
853 A=32
855 PRINT CHR$(A);
858 A=0
860 PRINTSTR$ (A*256+X) ;
863 A=13
864 PRINT CHR$(A);
867 A=0
869 POKE 212, A
871 X=PEEK(1024)
874 PRINT (A*256+X ) ;
877 X=X+1
878 IF X<>0 THEN 828
94
Programming Aids: 2
You can do a line-by-line comparison between the machine
language and BASIC versions of this program. For instance, line 033C
in the ML version is the same as line 828 in the BASIC program. Both
lines check to see if a key has been pressed. Comparing BASIC and
machine language versions in this way is one of the best ways to see
how ML operates, especially if you're unfamiliar with machine
language programming.
Program 1. ASCII/POKE Printer
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
10 FORJ=828T0879:READK:POKEJ,K:NEXT # : rem
15 READY : IFY< > 999THENSTOP * :rem 151
20 DATA32, 228, 255, 240, 251, 170, 201, 141, 208, 1,96, 169
,147 :rem 142
21 DATA32, 210, 255, 169, 255, 133, 212, 138, 32, 210, 255,1
69,32 :rem 190
22 DATA32, 210, 255, 169, 0,32, 205, 189, 169, 13, 32, 210, 2
55 :rem 40
23 DATA169, 0,133, 212, 174, 0,4, 32, 205, 189, 232, 208, 20
4 : rem 240
25 DATA999 :rem 44
Program 2. Disassembly
033C
JSR
$FFE4
033F
BEQ
$033C
0341
TAX
0342
CMP
#$8D
0344
BNE
$0347
0346
RTS
0347
LDA
#$93
0349
JSR
$FFD2
034C
LDA
#$FF
034E
STA
$D4
0350
TXA
0351
JSR
SFFD2
0354
LDA
#$20
0356
JSR
$FFD2
0359
LDA
#$00
035B
JSR
$BDCD
035E
LDA
#$0D
95
u
2: Programming Aids
LI
0360 JSR $FFD2
0363 LDA #$00
0365 STA $D4
0367 LDX $0400
036A JSR $BDCD
036D INX
036E BNE $033C
u
u
\ I
u
□
Thomas Henry
Key
How many times has this
happened to you? \bu're sit-
ting at your Commodore
64, entering or editing a pro-
gram, and through a series
of keystrokes that you prob-
ably don't even remember,
get into the following trap.
When you push a cursor
movement key, instead of the
cursor actually moving , you
get a reverse video field
symbol on the screen.
Frustrating, isn't it? As you
have probably learned,
about the only way to get
free of the trap is to hit RETURN to get out of the line, and then
start over.
Here's an easier way: a program that adds a valuable escape
option to your computer. With this feature, the seldom-used British
pound symbol (£) becomes an escape key. When you are stuck in
the cursor trap mentioned above, simply push the key; you will be
released from what's called the quote mode and will be free to move
the cursor as desired. Before looking at the program, let's examine the
problem in greater detail.
Store or Perform the Action
Some of the computer's keys are able to perform two distinct jobs,
depending on whether the computer is in the immediate or program
mode. These keys include the four cursor keys, RVS ON, RVS OFF,
CLR, HOME, INST (Insert), DEL (Delete), and all of the color selec-
tion keys. In the immediate mode you push one of these keys and the
action is performed immediately. For example, depress the cursor
right key and the cursor moves one space to the right.
But one of the truly impressive features of your Commodore
computer is its ability to store or save the action implied by the key.
For example, here's a one-line program:
10 PRINT " { RIGHT } HELLO "
The string contains the word HELLO preceded by a cursor-right.
When you type this line into the computer, the cursor-right movement
64 Escape
While programming, there are
lots of ways to get trapped inside
quotes and be unable to use
the cursor controls. Until now,
your only recourse was to hit
RETURN and try the line again.
With this handy utility, you
can escape from "quote mode"
traps by just hitting the pound
sign key. The routine also serves
as an example of machine lan-
guage programming for those
who are interested in trying
their hand at it.
97
2: Programming Aids
u
jj
is not performed; instead it is stored in the string. The cursor-right
will be performed only when the program is run. We are storing a
cursor movement to be executed later in the program mode. To [_J
indicate that a cursor-right movement is stored in the string, the com-
puter will leave a reverse video field brace symbol inside the quotes.
In fact, every one of the keys mentioned above has a reverse video ) I
field character which stands for it when it's inside quotes. "~ '"
The trouble comes when the computer thinks you're trying to
store an action, but you want to perform it. There are a number of
ways this can happen. One way is if you've typed in an odd number
of quote marks while entering a line. Another way is pushing the
insert key more times than you expected.
Escape by Machine Language
Having defined the problem, let's look at a program that will take care
of it. Examine Program 1. This is the source code of the Escape Key
program. Since assemblers are now becoming quite common for
the 64, enterprising users might wish to enter the source code in
directly and assemble their own version. If you're an experimenter,
you'll find that this is a great program to begin with. It's not too
long, and yet not so short as to be just a trivial exercise. And it has a
practical use too.
Examine Program 1. The first part shows the "equates" for the
program. These equates give names or labels to the various internal
addresses that are used by the program. For example, NOKEYS stands
for location $C6, and this location always contains the number of
keystrokes stored in the keyboard buffer. IRQVEC stands for the IRQ
vector stored in RAM (Random Access Memory). And so it goes for
all of the labels. Each stands for a location, and usually the label
suggests the meaning of the location in question.
The IRQ Routine
The escape key initialization occurs next. A new vector is stuffed
into RAM, and this vector directs the computer to always jump to
the start of the new IRQ routine. This routine occurs next in the
listing. As this is the heart of the whole program, let's examine it
in greater detail. ! j
The first thing that happens here is that all of the registers are
saved temporarily. Next, the last key depressed is examined. If it
wasn't the British pound symbol (which is used for the escape key), M
the registers are restored and the normal IRQ is finished. But if it is
the desired key, a zero is stored in three important locations. These
are CMODE, RE VERS, and NOINST. Stuffing a zero in CMODE turns [J
98
Li
Programming Aids: 2
off the quote mode, a zero in REVERS turns off the reverse screen
mode, and a zero in NOINST nulls out the number of inserts pend-
ing. TUrning off these three locations allows you to escape from all
of the "offending" modes.
Blanking the Pound
Recall that a British pound symbol has been printed to the screen.
A true escape key shouldn't print anything; it should simply "escape."
So the next block of code deposits a blank on top of the British
pound character and backs the cursor up one space. The net effect is
that no residual character is printed. So a true escape key has
been implemented.
Before going on to the rest of the normal IRQ routine (called
IRQRTN in Program 1), the registers are restored. We have kept
the new routine transparent to the normal Commodore 64
operating system.
You might wish to assemble your own version of this program.
Most users, however, will want to use the BASIC loader in Program
2. This loader puts the program into the top of memory.
Make an Escape
To prepare a copy of this program for use, follow these steps:
1. Type in Program 2.
2. Check for errors.
3. SAVE the program first.
4. Now try it out. Type RUN and hit RETURN.
5. Almost instantly, the program will relocate to the top of
memory and perform a self-initialization. You may leave the
program in place for the duration of a programming session;
it will not interfere with normal BASIC operation.
Typing NEW will not affect the escape key program, but if you hit
the RUN/STOP-RESTORE key combination, the program is disabled.
You can reenable it quite easily by typing:
SYS 2 56 * PEEK(56) + PEEK(5 5)
Since cassette operations affect the IRQ loop, you may wish to
disable the escape option with a RUN/STOP-RESTORE before
doing any loading or saving and reenable it afterwards with the
SYS 256*PEEK(56) + PEEK(55).
If you have the program in place, try it out. For example, type
a quote mark. Now hit the cursor right key a number of times.
Do you see the reverse video field brace? Now hit the British pound
]
99
2: Programming Aids
key. Then hit the cursor key once more. Notice that this time you
actually move to the right. Think of the most outlandish combina-
tion of keystrokes that you can, then try the escape. The quote mode
is powerless to hold your cursor.
Program 1
NOKEYS =
RE VERS
ROW
COLUMN =
CMODE
INKEY
NOINST
KEYBRD =
IRQVEC
IRQRTN =
Disassembly of 64 Escape Key
NEWIRQ
$C6
$C7
$D1
$D3
$D4
$D7
$D8
$0277
$0314
$EA31
SEI
LDX #<NEWIRQ
LDY #>NEWIRQ
STX IRQVEC
STY IRQVEC + 1
CLI
RTS
PHA
TXA
PHA
TYA
PHA
LDA
CMP
BNE
LDX
STX
STX
STX
INX
STX
LDY
DEY
LDA
STA
LDA
STA
INKEY
#$5C
MOVEON
#$00
CMODE
RE VERS
NOINST
NOKEYS
COLUMN
#$20
(ROW), Y
#$9D
KEYBRD
NUMBER OF KEYS IN BUFFER.
SCREEN REVERSE FLAG.
CURRENT CURSOR ROW.
CURRENT CURSOR COLUMN.
CURSOR MODE:0 = DIRECT.
LAST KEYSTROKE IN.
NUMBER OF INSERTS PENDING.
KEYBOARD BUFFER.
IRQ VECTOR.
NORMAL IRQ ROUTINE.
;SET UP NEW IRQ VECTOR.
; RETURN TO BASIC.
;SAVE ALL REGISTERS.
GET LAST KEY PUSHED.
IS IT BRITISH POUND SIGN?
BRANCH IF NOT.
YES.
TURN QUOTE MODE OFF.
TURN REVERSE MODE OFF.
TURN INSERT MODE OFF.
TELL THE KBD BUFFER THAT
IT CONTAINS ONE KEYSTROKE.
MOVE CURSOR BACK ONE SPACE.
THEN DEPOSIT A BLANK.
FINALLY, PUT A CURSOR LEFT
IN THE KEYBOARD BUFFER.
U
U
U
U
u
100
U
u
u
u
□
Programming Aids: 2
MOVEON PLA ;RESTORE ALL REGISTERS.
TAY
PLA
TAX
PLA
JMP IRQRTN ;FINISH NORMAL INTERRUPT.
Program 2. Escape Key BASIC Loader
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
100 T=256*PEEK(56)+PEEK(55)-55:GOSUB160 : rem 189
110 POKE56,HI%:POKE55,LO :rem 168
120 FORA=TTOT+54 : READD : POKEA , D :NEXT : rem 4
130 X=T : T=T+13 :GOSUB160 : POKEX+2 , LO : POKEX+4, HI%
:rem 99
140 SYS(X) :rem 61
150 NEW :rem 128
160 HI%=T/256:LO=T-HI%*256:RETURN :rem 212
170 DATA120,162,13,160,16,142,20,3 : rem 160
180 DATA140,21,3,88,96,72,138,72 : rem 95
190 DATA152,72,165,215,201,92,208,23 :rem 26
200 DATA162, 0,134, 212, 134, 199, 134, 216 :rem 66
210 DATA232,134,198,164,211,136,169,32 : rem 128
220 DATA145,209,169,157,141,119,2,104 :rem 76
230 DATA168,104,170,104,76,49,234 : rem 139
101
E. A. Cottrell
Variable Lister
You almost always use variables There are two types of
when you write a BASIC pro- variables, simple and array,
gram. Sometimes, though, in a and three categories in
long program, you can lose each tv P e ' floatingpoint
track of them. This utility lists numeric, integer numeric,
all your variables in order, and f™^ AU of j hese h
including variable tvtoe such vanables ^ stored m tne
tnciuamg variame lypesuco 4 j^^^ above ^
as simple or array Its an MSIC ^
especially helpful tool for writ- T £ e simple
ing program documentation. ^ stored below the a^ys
starting at the address pointed to by memory locations 45 and 46
(see box). Each of these simple variables occupies seven bytes of
memory. The first two bytes contain the first two characters (in ASCII
code) of the name of the variable, with coding to indicate which
type of variable it is. This coding is accomplished by adding 128 to
both characters if it is an integer variable and by adding 128 to the
second character if it is a string variable. No coding indicates a float-
ing point variable. The remaining bytes in numeric variables contain
the value of the variable. In the case of string variables, the remain-
ing bytes contain the length of the string and the location at the top
of memory which contains the first character of the string.
Arrays are quite different in that the length of the variable is
determined by the number of elements in the array. The information
which must be stored for an array variable includes the name of the
variable, which is coded the same as for a simple variable, a pointer
to the location of the next variable, the number of dimensions in
the array, and the number of elements in the array.
In addition, the value of each element in numeric arrays, or the
pointer to the string and its length for string arrays, must be stored.
As you can see, array variables can eat up a lot of memory in a hurry.
It is best to use the lowest possible number of elements in your arrays.
If you do not specify the size of an array, the computer will set it
at eleven elements. If you need less than eleven, you'll save a mini-
mum of five bytes per element if you establish the size of the array
with a DIMension statement. Although a simple integer variable takes
up the same amount of memory as a simple floating point variable,
three bytes per element can be saved if you use integer instead of
floating point variables in arrays.
102
Programming Aids: 2
Address Pointers
Now and then you'll see a reference to "pointers" within the com-
puter's memory. These are two-byte long numbers, usually located
in the first 256 memory cells of the computer, which hold an
important address.
Things change while a program is running or being written, For
example, if you add a line to a BASIC program, you've expanded the
amount of space that the program is taking up in RAM memory. Obvi-
ously, when you go to save the program, the computer has to know
where the BASIC program ends. So, it keeps track of the "current
top of BASIC program' ' in a pointer. This pointer is located in the 64
in addresses 45 and 46. The number held in cell 46 is multiplied
by 256 and then added to the number in cell 45. lb see at which
address in RAM memory your current BASIC program ends, you
can type: ? PEEK (45) + PEEK (46) * 256.
There are a number of other pointers as well, including "limit
of memory," "start of arrays," "string storage," and "start of BASIC."
The locations of these pointers are listed in memory maps for each
computer. The best memory map for the Commodore 64 is Map-
ping the 64, by Sheldon Leemon, published by COMPUTE! Books.
There are some interesting things you can do by manipulating
these pointers with POKEs. For one thing, you could fool the com-
puter into reserving space for programs in odd places, or even parti-
tioning memory so that two independent BASIC programs could
run simultaneously. In any event, pointers hold information essen-
tial to the computer, and their values can be accessed using the
formula above.
LOADing the Lister
"Variable Lister" is a machine language (ML) program which is loaded
by BASIC POKEs, thus eliminating the need for an assembler. The
ML is automatically loaded into the top of memory and protected
from your BASIC program. Before you run the program, be sure to
save a copy since it self-destructs after it is run. When the machine
language is loaded, the loader program gives you the location to
SYS to when you want to list your variables. For example, when you
first use this on the 64, you would type SYS 40704 to list your vari-
ables. The program then lists the simple variables in the order of
appearance in the program, with indicators of their type. Next the
array variables are listed with proper indicators.
103
2: Programming Aids
To use Variable Lister, first load and run it. Note the SYS number
you'll later enter. Next, load the program whose variables you want
to list. Type RUN. The BASIC program has to be run before you give
the SYS to start the Lister. This is because the variables of a BASIC
program are not set up in memory until it's run. Break out of the pro-
gram by pressing the RUN/STOP-RESTORE keys, then enter the
correct SYS (which Lister gave you earlier).
What you'll see on the screen is a list of the simple variables in
the order of appearance in the program, along with indicators of
their type. Next the array variables are listed with proper indicators.
Function variables (in the form fn(x)) are noted by an asterisk (*).
Variable Lister is especially useful when you write programs
with many variables and have to find new names. It is also valuable
for documenting programs once they're completed.
The variables are listed across the screen to prevent them from
scrolling out of view. If you have a printer, the following changes
may be made to give you a listing which may be easier to read.
160 IF PA<>35126 THEN PRINT "DATA ERROR" :END
260 DATA 32,210,255,169,13,32,210
420 DATA 41,32,210,255,169,13,32
To send the list to your printer, simply OPEN a file to your printer :
OPENl,4 :CMD1 :SYSXXXXX
Variable Lister
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
120 ME=PEEK(55)+256*PEEK(56) :rem 21
130 VS=ME-256:PA=0 :rem 14
140 POKE 56,PEEK(56)-1 : rem 154
150 FOR I=VS TO VS+253:READ A: POKE I , A : P A=PA+A : NEX
T :rem 241
160 IF PA035164 THEN PRINT "DATA ERROR" :END
:rem 233
170 PRINT"SYS" VS "TO START" :NEW : rem 170
180
DATA
165,45,197,47,
240,106,133
: rem 144
190
DATA
253,165,46,133
,254,160,0
: rem 85
200
DATA
169,0,141,61,3
,177,253
:rem 237
210
DATA
41,128,208,73,
177,253,41
:rem 87
220
DATA
127,32,210,255
,200,173,61
:rem 120
230
DATA
3,201,0,208,8,
177,253
: rem 184
240
DATA
41,128,208,59,
240,11,177
: rem 87
245
DATA
253,41,128,208
,5,169,42,141,61,3,
177,253,
41
: rem 2
250
DATA
127,32,210,255
,173,61,3
:rem 28
260
DATA
32,210,255,169
,32,32,210
:rem 75
270
DATA
255,152,24,105
,6,144,5
:rem 239
104
Programming Aids: 2
280 DATA 164,254,200,132,254,168,101 : rem 230
290 DATA 253,197,47,240,17,208,173 :rem 150
300 DATA 96,169,37,141,61,3,208 :rem 248
310 DATA 176,169,36,141,61,3,208 : rem 39
320 DATA 203,165,49,197,47,240,114 :rem 141
330 DATA 165,47,133,253,165,48,133 :rem 143
340 DATA 254,160,0,169,0,141,61 :rem 232
350 DATA 3,177,253,240,216,41,128 : rem 85
360 DATA 208,77,177,253,41,127,32 : rem 96
370 DATA 210,255,200,173,61,3,201 : rem 69
380 DATA 0,208,6,177,253,41,128 :rem 246
390 DATA 208,63,177,253,41,127,32 :rem 94
400 DATA 210,255,173,61,3,32,210 :rem 18
410 DATA 255,169,40,32,210,255,169 :rem 139
420 DATA 41,32,210,255,169,32,32 :rem 27
430 DATA 210,255,200,177,253,24,101 :rem 171
440 DATA 253,197,49,240,39,177,253 :rem 157
450 DATA 24,101,253,170,200,177,253 :rem 176
460 DATA 101,254,133,254,134,253,208 :rem 231
470 DATA 165,96,169,37,141,61,3 :rem 2
480 DATA 208,172,169,36,141,61,3 :rem 43
490 DATA 208,186,165,48,197,50,208 :rem 160
500 DATA 136,96,200,234,177,253,101 :rem 182
510 DATA 254,197,50,240,224,16,222 :rem 132
520 DATA 136,208,202 : rem 209
105
Eric Brandon
Disk Defaulter
Short and simple, this machine When Commodore designed
language routine saves typing the operating system used
if you regularly use a disk drive in the Commodore 64, the
instead of a cassette recorder. designers assumed that most
SAVES, IDADs, and VERIFYs P eo P le would be using a
automatically default to disk cassette reorder for ster-
ol *» * 1 / age instead of the more
rather than tape when you ^ pensive disk ^ That - S
have this routine in memory. why, when you type LOAD
or SAVE, the computer responds by prompting "Press Play On Tape"
or "Press Record & Play On Tape." It defaults to the tape recorder.
If you're using a disk drive, you have to type the device number
— ,8 — after each command (as in LOAD "filename", 8). This can
become bothersome after a while.
"Disk Defaulter" is a short utility, written in machine language,
that modifies the computer's operating system to recognize the disk
drive, instead of the cassette recorder, as the default device. As long
as the utility is activated, you no longer have to append ,8 to the
LOAD, SAVE, and VERIFY commands.
To use Disk Defaulter, enter the program. When you type RUN,
this BASIC loader POKEs the machine language into some free
memory space and activates the utility. To turn it off (for instance, if
you want to use cassette), press RUN/STOP-RESTORE. To turn it
back on, type SYS 679.
To load machine language programs, you still must type LOAD
"filename",8,l. Also, pressing SHIFT-RUN/STOP will not access the
disk drive because it results in a "Missing Filename Error." But other-
wise, all LOAD, SAVE, and VERIFY commands will refer to disk.
The only program we've found that interferes with Disk Defaulter
is the PAL Assembler for the Commodore 64.
Disk Defaulter
For mistake-proof program entry, be sure to read "The Automatic Proofreader" Appendix C.
10 1=679 :rem 141
20 READ A: IF A=256 THEN 1000 : rem 147
30 POKE I, A: 1=1+1: GOTO 20 :rem 130
679 DATA 169,188,141,48,3,169,2 : rem 16
686 DATA 141,49,3,169,195,141,50 trem 54
693 DATA 3,169,2,141,51,3,96 : rem 103
106
Programming Aids: 2
700 DATA 162,8,134,186,76,165,244 :rem 100
707 DATA 162,8,134,186,76,237,245,256 :rem 53
1000 PRINT" {CLR} DISK DEFAULTER ACTIVATED" : rem 129
1010 PRINT"USE RUN/ STOP-RESTORE TO DEACTIVATE"
:rem 184
1020 PRINT "TYPE SYS 679 TO REACTIVATE" : rem 6
1030 SYS 679 :rem 105
107
□
□
□
□
□
D
□
Chapter 3
High-Speed
Graphics
□
□
□
□
□
D
□
Charles Brannon
Ultrafont +
Character Editor
This fast, feature-packed, Anyone who has used graph
machine language utility paper to plot out characters,
makes custom characters a then tediously converted
breeze. Its unique features let the rows ^to decimal
you concentrate on your art- numbers, can appreciate
work instead of programming. * character editor. Instead
J ^ d of drawing and erasing on
paper, you can draw your characters freehand with a joystick. "Ultra-
font + " has been written to offer almost every conceivable aid to
help you design whole character sets.
Typing It In
Ultrafont + is written entirely in machine language, giving you speed
and efficiency that BASIC can't match. Although this gives you a prod-
uct of commercial quality, it carries the liability of lots of typing.
Ultrafont + is actually rather short, using less than 4K of memory at
hexadecimal location $C000 (49152), which is reserved for programs
like Ultrafont + . Therefore, you don't lose one byte of BASIC
programming space.
However, 4000 characters require three times as much typing,
since each byte must be represented by a three-digit number (000-
255). With that much typing, mistakes are inevitable. To make things
manageable, we've prepared Ultrafont + to be typed in using MLX,
the Machine Language Editor. Full instructions are provided in
Appendix D. So despite the typing, rest assured that a few afternoons
at the keyboard will yield a substantial reward.
Once you've entered, saved, and run MLX, answer the two
questions, starting address and ending address, with 49152 and
52409, respectively. After you've saved the program with MLX,
you can load it from disk with LOAD "filename", 1,1 from tape or
LOAD "filename",8,l from disk. After it's loaded, enter NEW, then
SYS 49152. This command runs the machine language program at
SC000 (12*4096 = 49152).
The Display
After you SYS to Ultrafont + , you should see the work area. At the
bottom of the screen are eight lines of characters. These are the 256
characters you can customize, arranged in eight rows of 32 charac-
ters. A flashing square is resting on the @ symbol, the home position
ill
3: High-Speed Graphics
of the character set. Above the eight rows is the main grid, a blown-
up view of ten characters. The last row of the screen is reserved for
messages. The first time you SYS 49152, you'll be asked whether you
want to edit the uppercase/graphics character set, or the lowercase set.
About the Grid
The grid is like a large-sized window on the character set. \bu see the
first five characters and the five beneath them. A large red cursor
shows you which character you are currently editing, and a smaller
flashing square is the cursor you use to set and clear pixels in order
to draw a character.
Moving Around
You can use the cursor keys (up, down, left, right) to move the large
red cursor to any character you want to edit. If you move to a char-
acter not on the large grid (out of the window), the window will auto-
matically scroll to make the character appear. You can also look at
the bottom of the screen to move the larger cursor, as the flashing
square on the character set moves with the main grid.
The HOME key moves the small cursor to the upper-left corner
of the screen. If you press it twice, it will take you back to the top of
the character set — to @.
A joystick (plugged into port 2) moves the small cursor within
the grid. If you move the cursor out of the current character, the
red cursor will jump to the next character in whatever direction you
want to move. The display at the bottom will adjust, and the grid
will scroll as necessary. This means that you can ignore the traditional
boundaries between characters, and draw shapes as big as the entire
character set (256 x 64 pixels — a pixel is a picture element, or dot).
You can still edit one character at a time, or make a shape within a 2
x 2 box of characters. There is no wraparound for the cursor in the
bottom section of the screen. When it hits an edge, it will go no
further in that direction.
The fire button is used to set and clear points. When you press
fire, if the cursor is resting on a solid square, it will be turned off. If
the square is off, it will be turned on. If you hold down the fire but-
ton while you move the joystick, you can stay in the same drawing
mode. If you set a point, you will continue to draw as you move. If
you clear a point, you can move around and erase points all over
the screen.
If the drawing cursor is too fast or too slow to use, just press V
to set the cursor velocity (speed). Answer the prompt with a speed
from (slow) to 9 (too fast for practical use).
112
High-Speed Graphics: 3
Manipulations
There are several functions that affect the current character (where
the red box is). You can rotate, shift, mirror, reverse, erase, replace,
and copy characters. The best way to learn is to play with the func-
tions. It's really a lot of fun. The following keys control each function:
Function Keys
f 1: Scroll character right. All pixels move right. The rightmost
column of pixels wraps around to theleft.
f2: Scroll character left. Wraparound is like f 1.
f3: Scroll character down. All pixels move down. The last row of
pixels wraps around to the top.
f4: Scroll character up. Wraparound is like f3.
R: Rotate. Rotates the character 90 degrees. Press twice to flip the
character upside down.
M: Mirror. Creates a mirror image of the character left to right.
CLR (SHIFT— CLR/HOME): Erases the current character.
CTRL-R or CTRL-9: Reverses the character. All set dots are clear,
and all empty dots are set. The bottom half of
the character set is the reversed image of the
top half.
CTRL-back arrow ( +- ): This causes the lower half of the charac-
ter set to be the inverse of the upper
half. This way, you only have to redraw
the normal characters, then use CTRL-
back arrow to create the inverse set.
F: Fix. Use this if you want to restore the normal pattern for the
character. If you've redefined A, and press F while the red cursor
is on the character, the Commodore pattern for A will be copied
back from ROM.
T: Type. This lets you try out your character set. The screen clears,
with a copy of the character set provided for reference. You can
type and move the cursor around, just as in BASIC. This is handy
for envisioning sample screens, and fitting together multiple-
character shapes. If you want to change the background color
while in Type mode, press the f 1 key. Cycle through the colors
by repeatedly hitting the f 1 key. Press the RUN/STOP key to exit
from Type and return to Ultrafont + .
Saving and Loading Character Sets
To save your creation to tape or disk, press S. Then press either T for
tape or D for disk. When requested, enter the filename, up to 16
113
3: High-Speed Graphics
characters. Don't use the 0: prefix if you're using a disk drive (it's
added for you). The screen will clear, display the appropriate mes-
sages, and then return to the editing screen if there are no errors. If
there are errors, such as the disk being full, Ultrafont + will read the
disk error message and display it at the bottom of the screen.
Press a key after you've read the message and try to correct the
cause of the error before you save again. The computer cannot detect
an error during a tape SAVE.
To load a character set previously saved, press L and answer the
TAPE OR DISK message. Enter the filename. If you're using tape, be
sure the tape is rewound and ready. After the load, you will be
returned to the editing screen, and a glance is all it takes to see that
the set is loaded. If an error is detected on tape load, you will see
the message ERROR ON SAVE/LOAD. Once again, if you are using
disk, the error message will be displayed. Press a key to return to
editing so you can try again.
Copying and Moving Characters
You can copy one character to another with function keys 7 and 8.
When you press f 7, the current character will flash briefly, and it
will be copied into a little buffer. Ultrafont + will remember that char-
acter pattern. You can then position the cursor where you want to
copy the character and press f8. The memorized character will then
replace the character the cursor is resting on. You can also use the
buffer as a fail-safe device. Before you begin to edit a character you've
already worked on, press f7 to store it safely away. That way, if you
accidentally wipe it out or otherwise garble the character, you can
press f8 to bring back your earlier character.
Creating DATA Statements
A very useful command, CTRL-D, allows you to create DATA state-
ments for whatever characters you've defined. Ultrafont + doesn't
make DATA statements for all the characters, just the ones you've
changed. After you press CTRL-D, Ultrafont + adds the DATA state-
ments to the end of whatever program you have in BASIC memory.
If there is no program, the DATA statements exist alone.
You can LOAD Ultrafont + , enter NEW to reset some BASIC
pointers, LOAD a program you are working on, then SYS 49152 to
Ultrafont + to add DATA to the end of the program. The DATA state-
ments always start at line 63000, so you may want to renumber them.
If you press CTRL-D twice, another set of DATA statements will be
appended, also numbered from line numbers 63000 and up. Since the
keys repeat if held down, just tap CTRL-D. If you hold it down,
114
High-Speed Graphics: 3
you may find a hundred DATA statements have been created! See the
notes at the end of this article for more details on using the DATA
statements in your own programs.
Exiting Ultraf ont +
After you create the DATA, you'll still be in Ultrafont + . If you want
to exit to see the DATA statements or go on to other things, press
CTRL-X. The screen will reset to the normal colors and you'll see
READY. If you've made DATA, a LIST will dramatically reveal it. I
recommend you enter the command CLR to make sure BASIC is ini-
tialized properly after creating DATA statements. One thing to watch
out for: Don't use RUN/STOP-RESTORE to exit Ultrafont + . Ultra-
font + moves screen memory from the default area at 1024, and the
RUN/STOP-RESTORE combination does not reset the operating sys-
tem pointers to screen memory. If you do press it, you will not be
able to see what you are typing. To fix it, blindly type POKE 648,4
or SYS 49152 to reenter Ultrafont + so you can exit properly.
Reentering Ultrafont +
To restart Ultrafont + within the program, press SHIFT-RUN/STOP.
After you've exited to BASIC, you can rerun Ultrafont + with SYS
49152. You'll see the character set you were working on previously,
along with the message USE ROM SET? (Y/N). Usually, Ultrafont +
will copy the ROM character patterns into RAM where you can change
them. If you press N, however, the set you were working on pre-
viously is left untouched. Press any other key, like RETURN, to reset
the characters to the ROM standard. You can copy either the upper-
case/graphics set from ROM, or the lowercase set.
A Whole New World of Multicolor
We're not finished yet. There is a whole other mode of operation
within Ultrafont + : the multicolor mode. In multicolor mode, any
character can contain up to four colors (one has to be used for the
background) simultaneously. Multicolor changes the way the com-
puter interprets character patterns. Instead of a 1 bit representing a
solid pixel and representing a blank, the eight bits are organized as
four pairs of bits. Each pair can represent four possibilities: 00, 01,
10, and 11. Each of these is also a number in decimal from to 3.
Each two-bit pattern represents one of the four colors. Programming
and using multicolor characters are described in my article 'Advanced
Use of Character Graphics," found in COMPUTEl's First Book of 64
Sound and Graphics.
115
3: High-Speed Graphics
Ultrafont + makes multicolor easy. You don't have to keep track
of bit-pairs any more than you have to convert binary to decimal.
Just press the f 5 function key. Presto! The whole screen changes. The
normal characters are rather unrecognizable, and the drawing cursor
is twice as wide (since eight bits have been reduced to four pixel-pairs ,
making each dot twice as wide). You have only four dots horizon-
tally per character, but you can easily combine many characters to
form larger shapes.
Multicolor also redefines the way the joystick and fire button
work. The fire button always lays down a colored rectangle in the
color you are currently working with. That color is shown in the
center of the drawing cursor. Press the number keys 1, 2, 3, or 4 to
choose one of the four different colors to draw with. The number of
the key is one more than the bit pattern, so color 1 is bit pattern 00,
and color 4 is bit pattern 11. When you first SYS to Ultrafont + , the
four colors show up distinctly on a color TV or monitor.
You can easily change the colors. Just hold down SHIFT and press
the appropriate number key to change that number's color. You will
see the message PRESS COLOR KEY. Now press one of the color keys,
from CTRL-1 to CTRL-8 or from Commodore-1 to Commodore-8.
Hold down CTRL or the Commodore key as you do this. Instantly,
that color, and everything previously drawn in that color, is changed .
Three of the colors (including 1, the background color) can be
any of the 16 colors. But because of the way multicolor works, color
4 (represented by bit pattern 11, or 3 in decimal) can only be one of
the 8 CTRL-colors. Assigning it one of the Commodore colors just
picks the color shown on the face of the color key. Incidentally, it is
the color of bit pattern 3 (color 4) that changes according to the
character color as set in color memory. The other colors are pro-
grammed in multicolor registers 1 and 2 (POKE 53282 and 53283),
so all characters share these two colors. When you want to vary a
certain color without affecting the rest of the characters, you'll want
to draw it in color 4.
Some of the commands in the multicolor mode aren't as useful
as others. You have to press f 1 and f2 twice to shift a character,
since they only shift one bit, which causes all the colors to change.
You can use CTRL-R, Reverse to reverse all the colors (color 1 becomes
color 4, color 2 becomes color 3, and color 3 becomes color 2). R:
(Rotate) changes all the colors and is rather useless unless you press
it twice to just turn the character upside down. M: (Mirror) will
switch colors 2 and 3 , since bit pattern 01 (color 2) becomes 10 (color
3). You can still copy characters using f7 and f8 (see above).
116
High-Speed Graphics: 3
Returning to Normal
You can switch back instantly to the normal character mode by press-
ing f6. If you were drawing in multicolor, you can see the bit pat-
terns that make up each color. Multicolor characters look just as
strange in normal mode as normal characters look in multicolor.
If you changed colors in the multicolor mode, some of the col-
ors in the normal mode may have changed. You can change these
colors as in multicolor mode. Press SHIFT-1 to change the color of the
empty pixels, and SHIFT-4 to change the color of the eight rows of
characters. Use SHIFT-2 to change the color of the on pixels.
Programming
You'll find the article "Advanced Use of Character Graphics " in
COMPUTERS First Book of 64 Sound and Graphics quite informative .
It shows you how you can make the most of characters. The
article includes several short machine language utilities that you can
use when writing games or other programs using these custom char-
acters. It shows how your program can read the SAVEd files directly,
without having to POKE from DATA statements. You should still have
a good grasp of the essentials of programming characters (see Orson
Scott Card's "Make Your Own Characters," also in COMPUTE! 's First
Book of 64 Sound and Graphics). Ultrafont + is intended as an
artistic aid in your creations, letting the computer take over the
tedious tasks it is best suited for.
Notes: How to Use the DATA Statements
The DATA statements are created from lines 63000 and up. Each line
of data has nine numbers. The first number is the internal code of
the character (the code you use when POKEing to the screen). It rep-
resents an offset into the table of character patterns. The eight bytes
that follow are the decimal numbers for the eight bytes it takes to
define any character. A sample program to read and display them
could be:
10 POKE 56,48:CLR
50 READ A: IF A=-l THEN 70
60 FOR 1=0 TO 7 : READ B:POKE 12288+A*8+I,B:NEXT:GOT
050
70 PRINT CHR$(147) {10 DOWN}":REM TEN CURSOR DOWN
S
80 FOR I=0TO7:FORJ=0TO31:POKE1028+J+I*40,I*32+J:PO
KE 5 5 3 0+ J+ 1 * 40 , 1 : NEXT : NEXT
90 POKE 53272, (PEEK( 53272 )AND240)OR 12:END
117
3: High-Speed Graphics
You'll also need to add the following line to the end of your DATA
statements:
63999 DATA -1
If you want to have your cake and eat it, too — that is, also have the
normal ROM patterns — copy the normal patterns from ROM down
to RAM by adding:
20 POKE 56334, PEEK(56334)AND254:P0KE 1,PEEK(1)AND2
51
30 FOR 1=0 TO 2047:POKE 12288+1 , PEEK( 53248+1 ) :NEXT
40 POKE 1, PEEK (U0R4: POKE 56334,PEEK(56334)0R1
Quick Reference: Ultrafont + Commands
Cursor keys:
Move to next character
HOME(CLR/HOME):
Move the cursor to Upper-left corner
Press twice to go back to start
V:
Cursor velocity; answer from (slow)
to 9 (fast)
fl:
Scroll right with wraparound
f2(SHIFT-fl):
Scroll left
f3:
Scroll down
f4(SHIFT-f3):
Scroll up
R:
Rotate 90 degrees; press twice to invert
M:
Mirror image
SHIFT-CLR/HOME:
Erase current character
CTRL-R or CTRL-9:
Reverse pixels
CTRL-back arrow («-) Copy first four rows, inverted, to
or CTRL-F:
last four
F:
Fix character from ROM pattern
L:
Load. Tape or Disk, Filename
S:
Save. Tape or Disk, Filename
T:
Typing mode; RUN/STOP to exit
f5:
Switch to multicolor character mode
f6(SHIFT-f5):
Return to normal character mode
fl:
Memorize character (keep)
f8(SHIFT-f7):
Recall character (put)
CTRL-D:
Make DATA statements
SHIFT-RUN/STOP:
Restart Ultrafont +
CTRL-X:
Exit Ultrafont + to BASIC
118
n
n
High-Speed Graphics: 3
n
n
Ultraf ont +
Besuretoread ' 'Using the Machine Language Editor: MLX, ' ' Appendix D, before typing in
this program.
49152 :076, 247, 196,000, 001,003,011
49158 : 004 , 000 , 001 , 003 , 004 , 000 ,018
49164 : 173, 048, 002, 072, 173,045,013
49170 :002, 141,048,002, 141,079, 175
491 76 : 002 , 032 , 047 , 193 , 104 , 141 , 03 1
49182 :048,002,169,100,133,252,222
49188 : 169, 000, 133, 251, 133, 167, 121
49194 : 169, 216, 133, 168, 169, 008, 137
49200 : 141, 040, 002, 169, 002, 141, 031
49206 : 042 , 002 , 169 , 005 , 141 , 041 , 198
49212 :002,174,003, 192, 173,079,171
49218 : 002 , 205 , 048 , 002 , 208 , 002 , 021
49224 : 162, 002, 142, 080, 002, 160, 108
49230 : 000, 177, 253, 170, 173, 063, 146
49236 :002, 240,003,076, 233, 192,062
49242 : 169, 207, 145, 251, 138, 010, 242
49248 : 170, 176, 008, 173, 080, 002, 193
49254 : 145, 167, 076, 112, 192, 173, 199
49260 : 004 , 192 , 145 , 167 , 200 , 192 , 240
49266 : 008, 208, 221, 024, 165, 251, 223
49272 : 105, 008, 133, 251, 133,167,149
49278 : 165, 252, 105, 000, 133, 252, 009
49284 : 105, 116, 133, 168, 024, 165, 075
49290 : 253, 105, 008, 133, 253, 165, 031
49296 : 254, 105, 000, 133, 254, 056, 178
49302 : 238 , 079 , 002 , 206 , 041 , 002 , 206
49308 : 173 , 041 , 002 , 208 , 156 , 056 , 024
49314 : 173 , 079, 002 , 233 , 005 , 141 , 027
49320 : 079, 002, 056, 165, 253, 233, 188
49326 : 039, 133, 253, 165, 254, 233, 227
49332 : 000 , 133 , 254 ,206 , 040 , 002 , 047
49338 : 173 , 040 , 002 , 240 , 003 , 076 , 208
49344 : 056, 192, 206, 042, 002, 173, 095
49350 : 042 , 002 , 240 , 030 , 169 , 008, 177
H 49356 :141, 040, 002, 024, 173,079,151
' 1 49362 :002, 105, 032, 141, 079, 002, 059
49368 : 024, 165, 253, 105, 248, 133, 120
_ 49374 :253, 165, 254, 105, 000, 133, 108
IS 49380 :254,076,056, 192,096, 134,012
49386 : 097 , 169, 000, 141 , 043., 002 , 174
49392 : 006 , 097 , 046 , 043 , 002 , 006 , 184
f—| 49398 :097, 046, 043, 002, 174,043,139
\ I 49404 :002, 169, 207, 145, 251, 200, 202
49410 : 169, 247 , 145 , 251 , 136, 189, 115
49416 :003, 192, 145, 167, 200, 145, 092
|j 49422 :167, 200, 192,008, 208, 215, 236
119
3: High-Speed Graphics
49428 : 076, 117 ,192, 169 ,000 ,141, 203
49434 : 026 , 208 , 165 , 001 , 041 , 251 , 206
49440 : 133 , 001 , 096 , 165 , 001 , 009 , 181
49446 : 004, 133, 001, 169, 001, 141, 231
49452 : 026 , 208 , 096 , 169 , 000 , 133 , 164
49458 : 254, 173, 048, 002, 010, 133, 158
49464 : 253, 038, 254, 006, 253, 038, 130
49470 : 254, 006, 253, 038, 254, 169, 012
49476 :112 , 005, 254, 133 , 254, 096, 154
49482 :032,047,193,160,000,177,171
49488 : 253 , 073 , 255 , 145 , 253 , 200 , 235
49494 : 192, 008, 208, 245, 032, 012, 015
49500 : 192,096, 169, 102, 133, 252,012
49506 : 169, 218, 133, 168, 173,058, 249
49512 :002 , 174, 063 , 002 , 240 , 002 , 075
495 18 : 009 , 008 , 141 , 080 , 002 , 169 , 007
49524 : 132, 133, 251, 133, 167, 162, 070
49530 : 008, 169, 000, 133, 097, 160, 177
49536 :000, 165, 097, 145, 251, 230, 248
49542 : 097, 173, 080, 002, 145, 167, 030
49548 : 200 , 192 , 032 , 208, 240 , 024, 012
49554 : 165, 251, 105, 040, 133, 251, 067
49560 : 133 , 167 , 165 , 252 , 105 , 000, 206
49566 : 133, 252, 105, 116, 133, 168, 041
49572 : 202, 208,216,096,032,082,232
49578 : 203, 173, 044, 002, 141, 024, 245
49584 : 208 , 169 , 200 , 013 , 063 , 002 , 063
49590 : 141 , 022 , 208 , 169 , 000 , 141 , 095
49596 : 032 , 208 , 141 , 033 , 208 , 032 , 074
49602 :094, 193, 173,058,002, 174, 120
49608 : 063 , 002 , 240 , 002 , 009 , 008 , 012
49614 : 141, 134, 002, 165, 209, 133, 222
49620 : 243 , 024 , 165 , 210 , 105 , 116 , 051
49626 : 133, 244, 164, 211, 177, 209, 076
49632 :073, 128, 145, 209, 177, 243, 175
49638 : 072, 173, 134, 002, 145, 243, 231
49644 : 032 , 228 , 255 , 240 , 251 , 201 , 163
49650 : 133, 208, 006, 238, 032, 208, 043
49656 : 238 , 033 , 208 , 170 , 164 , 211 , 248
49662 : 177, 209, 073, 128, 145, 209, 171
49668 : 104, 145, 243, 138, 032, 210, 108
49674 .-255,032,225,255,208,193,154
49680 : 032 , 114 , 203 , 169 , 000 , 141 , 163
49686 : 134, 002 , 169 , 012 , 141 , 032 , 000
49692 : 208 , 076 , 141 , 196 , 032 , 023 , 192
49698 : 193, 169, 112, 133, 252, 173, 042
49704 : 082 , 002 , 133 , 254 , 162 , 008 , 169
49710 : 169, 000, 133, 253, 133, 251, 217
49716 :168, 177, 253, 145, 251, 200, 222
120
n
n
High-Speed Graphics: 3
H
n
49722
49728
49734
49740
49746
49752
49758
49764
49770
49776
49782
49788
49794
49800
49806
49812
49818
49824
49830
49836
49842
49848
49854
49860
49866
49872
49878
49884
49890
49896
49902
49908
49914
49920
49926
49932
49938
49944
49950
49956
49962
49968
49974
49980
49986
49992
49998
50004
50010
208,249,
202,208,
128,240,
254,076,
193,162,
157,002,
096,169,
116,133,
253,133,
177,251,
200,208,
252,202,
047,193,
010,008,
253,200,
076,012,
160,000,
010,040,
192,008,
192,032,
177,253,
253,136,
192,008,
136,145,
032,047,
253,133,
200,145,
200,165,
012,192,
000,169,
008,177,
202,208,
253,200,
076,012,
160,008,
002,136,
133,097,
133,007,
253,038,
166,097,
002,157,
165,097,
008,208,
002,145,
076,012,
160,000,
192,008,
192,120,
220,169,
230,254,230
242,165,252
007,169,208
044,194,032
004,189,006
192,202,208
112,133,252
254,169,000
251,168,162
073,255,145
247,230,254
208,240,096
160,000,177
074,040,042
192,008,208
192,032,047
177,253,074
106,145,253
208,242,076
047,193,160
133,097,200
145,253,200
208,245,165
253,076,012
193,160,007
097,136,177
253,136,016
097,145,253
032,047,193
000,133,097
253,010,102
250,165,097
192,008,208
192,032,047
169,000,153
208,250,169
152,170,169
177,253,074
007,202,016
165,007,029
049,002,198
016,224,200
215,136,185
253,136,016
192,032,047
152,145,253
208,249,076
169,127,141
001,141,026
,252,201
,201,054
,133,187
,035,199
,192,060
,247,072
,169,001
,133,137
,004,053
,253,242
,230,207
,032,130
,253,192
,145,199
,242,221
,193,188
,008,058
,200,146
,012,136
,000,028
,177,191
,200,091
,097,081
,192,242
,177,050
,253,233
,247,187
,076,132
,160,094
,162,025
,097,117
,145,031
,233,064
,193,040
,048,032
,007,016
,000,227
,145,045
,251,029
,049,037
,097,035
,192,174
,049,087
,248,092
,193,106
,200,214
,012,055
,013,078
,208,087
121
3: High-Speed Graphics
50016
50022
50028
50034
50040
50046
50052
50058
50064
50070
50076
50082
50088
50094
50100
50106
50112
50118
50124
50130
50136
50142
50148
50154
50160
50166
50172
50178
50184
50190
50196
50202
50208
50214
50220
50226
50232
50238
50244
50250
50256
50262
50268
50274
50280
50286
50292
50298
50304
169
027
141
021
208
242
002
208
141
141
025
104
208
173
169
037
208
000
000
000
000
085
064
064
064
064
000
000
001
000
084
084
050
079
083
079
146
082
083
076
058
082
082
085
077
032
095
069
032
141
017
003
088
177
018
024
239
208
208
104
169
158
208
141
169
049
064
064
064
064
000
000
000
000
000
000
001
000
001
065
043
095
032
086
068
080
018
063
078
069
067
075
069
083
089
085
067
082
018
208
169
096
208
208
208
013
173
169
168
177
141
141
022
001
234
000
000
000
000
064
064
064
064
085
255
001
255
018
070
032
069
079
069
095
069
068
095
065
078
079
069
032
069
047
146
065
032
208
169
195
173
039
173
173
063
057
001
104
141
024
033
208
141
085
076
076
064
000
016
016
016
016
080
255
000
001
085
079
086
082
078
047
018
032
146
070
077
084
076
089
082
084
078
080
083
018
210
014
009
001
098
184
190
192
235
075
167
067
052
201
134
255
140
210
228
222
109
211
132
138
144
235
249
004
009
193
222
093
044
164
214
203
015
225
015
252
021
245
022
016
000
181
108
045
191
169
118
141
018
169
044
022
002
002
141
170
018
208
208
238
025
064
064
064
064
000
000
000
000
000
000
255
255
000
076
078
046
082
032
076
084
079
073
073
069
069
079
095
079
063
041
080
069
076
177
141
020
003
201
141
141
041
022
033
208
064
169
032
200
208
076
064
076
076
085
080
016
016
016
016
000
001
000
255
082
032
146
082
065
065
065
032
075
069
095
032
032
083
032
040
018
082
079
122
n
n
High-Speed Graphics: 3
n
50310
146
079
087 ,
069,
082
063 , 148
50316
:095
169,
017 ,
160 ,
196
133 , 142
50322
251 ,
132,
252,
160,
040
169, 126
* rti o o
: feJoz t
13 J
iy i ,
1W J ,
loo
ZWti # ZW /
010 J J4
7 C0I
1 "7 "7
lift
OCT
Z3l |
z WJO j
Ziyi ,
0IO C 0IC 7
foy 3 , 103 z
701Q
ZWo
,
1 OC
1 Jo j
1 J Z j
0IQ 7
ioy /
13 Z i 114
, 0(74
10 / **
9 5 5
Z 3 3 i
01 56
10 jO
1 015
X 10 3
01901 941
10 ZJ0 / Z4X
C, CIO CO
* 1 Aft
1 ft 9
1 VJ Z
0194
IO
0194
01*39
YJ O j
9401 0(5ft
Z.'-tKJ | f JO
JtljJO
» 955
01 01 01
1 77
x / /
9 51
Z 3X
01*39 01*3*3
10 J Z f v J J
501*364
» 91 01
955
i & j j
901 0J
r z- c ic
1 96
r x 7 u
0Q7
144 011 01
501*3705
» 946
1 *3*3
f X J o
951
1 ^9
-L J i
959 094
501*376
~J*j *J 1 \J
• 1 601
PI 4 PI
1 69
0H9
YJ *j
i j j
191 177
X 7 X / X / /
c ,0f'3ft9
» 1 01*3
x iy «j
1 1ft
90ift
9501
Z -J IO
1 fi9
1 o z
0194 0165
C.0i "3QQ
310 O OO
; x d yj
Of 01 Of
r JOZ**
9A0I
f £4W
OCC -I CC
f Z3 3 / X 3 3
c 01 Q A
310 jy't
» 1 £01
, 000
OCT
Z Dl ,
ZI01
f kjy 3 f io /o
COM 0(01
. 7401
OlOfft
01*3
W J Z
7 1 01
Z1I0
91^ K
zDD
70101 1 40
ZIOVO / 14,3
3IO*rI0O
901ft
r Z4**
0(Q6
10y O
1 74
017ft
0101 7 0KOKC\
YjkJZ t 1010O
COM!
3IO*r X Z
» 9401
; Z**l0
1 601
XOI0
010101
101010 j
90101
901ft 019ft
Z10O f 10Z o
CAfA 1 ft
310'* XO
9019
z(0z
901ft
ZlOo
9501
ZDI0 ,
0IQA
W70
TOO 1 A A
f 1 / O / 144
c, 014 94
• 01 019
991
ZZ 1
010IQ
1010 J
1 4.1
141
0101 9 114
r I0I0Z f XX**
COM OCT
3J0**.J"I0
9 91
Z Z X
rl/J
MjVjxj
991
Z Z X ,
014.1
041
959 1 *3ft
Z 3 Z * X jo
C, 01 406
J 10** OO
• 0101 Q
; 1010 y
0101 9
V10Z
141
X**X (
101010 (
991
Z Z 1
1 6Q 01*34
XOy f KfO*T
1 0101
1 /IT
I'll
1 ^6
01019
1 fiQ
107
1 47 1 9*3
50144ft
955
1 69
Of Of Of
141 0155
X *T X f YJ ^ J
1 "34
01019
1 6Q
X O -7
0101ft
0119
J z
9 1 01 0165
50J460I
955
-j -j
1 ft 01
010(01
1 59
X J zi
1^1
19ft 1 01ft
501466
01 QQ
90101
011 6
K/X O
9 501
lOo
1 ft 5 1 Q4
50147
310** / Z
> 1 Q6
1? J
1 5^
X Z O j
OfQQ
70101 740
ZlOtO , Z4J
50I47R
1 99
X 7Z
019"?
V£J |
945
1 ft 01
1 OKI
0I0I0I 1 01^
YjXixj t X I0O
501 Aft A
» lo3
9 1 Q
i y d
ID J j
iy z
0IQO 0171
toy y ,io/i
3104:710
701 01
1 09
iy z
OI Q o
10 Jz
O 01Q
zWo |
Z4D
1 CO OIQOI
i oy , loow
310** 3D
> 1 CC
» 130
1 A 1
14 j.
oi yi A
OI0! O
loWz ,
ioy
ot i o one
lolz t \o /o
c oi C 0tO
1 A 1
141
13 Jz
ZkOo i
lo9,
1 o o
1ZO,
1/1 TO!
141 t 121
KOI C0IQ
3103 IOo
1 OQ
IJO |
(71 01 O
Oil*)
01Q C
iy d ,
1 /-Q IOC
ioy , lob
50(51 4
014ft
I0**o
1 41
141
0176
10 / O |
01017
1010 Z |
1 ftO
ID? ,
011 1 011 7
■0X1 fill /
5015901
1 41
0101 9
10)0 Z |
1 6Q
ID" j
01 Of 7
1 6Q 191
ID? / X ZX
501596
010(01
YJYJYJ
1 4.1
141
01 019
1 41
1 Tl ,
0145 91 5
KJ t ±D g Z X 3
5015*39
• 010(9
1 4.1
i*ti
0(6 "3
01019
IOIO Z i
1 71
1 / J ,
010(6 9*31
IOJOO t z JX
5015 *3R
1 99
X 7Z
0IPIQ
10 lu -7
0101ft
1 41
X*tX i
01017 010(4
1010 Z * KJV^t
50544
•173,
004
192 (
141 ,
034,
208 - 096
50550 i
173,
005,
192,
141,
035,
208,104
50556
•032,
012,
192,
032,
094,
193,167
50562 :
169
203,
205,
011,
192,
240,126
50568
017,
141,
011,
192,
162,
208,099
50574 i
142,
082,
002,
032,
032,
194,114
50580 i
032,
012,
192,
076,
170,
197,059
50586 ;
169,
098,
160,
196,
032,
145,186
50592
196,
032,
228,
255,
240,
251,082
50598 :
201,
078,
240,
029,
169,
117,232
123
3: High-Speed Graphics
50604
50610
50616
50622
50628
50634
50640
50646
50652
50658
50664
50670
50676
50682
50688
50694
50700
50706
50712
50718
50724
50730
50736
50742
50748
50754
50760
50766
50772
50778
50784
50790
50796
50802
50808
50814
50820
50826
50832
50838
50844
50850
50856
50862
50868
50874
50880
50886
50892
124
160
228
201
142
032
169
143
141
000
208
169
053
141
141
028
002
220
141
141
240
010
062
199
141
240
251
001
141
002
002
162
048
206
063
142
224
142
041
238
059
026
173
014
032
140
192
140
201
045
196
255
076
082
012
142
141
021
208
169
176
141
029
038
208
141
072
061
062
006
198
002
173
075
204
195
010
059
125
174
000
002
045
002
059
040
059
031
045
002
160
048
056
141
060
016
060
224
002
032
240
208
002
192
141
249
208
169
051
141
002
208
208
169
060
041
002
002
032
032
208
062
002
174
172
024
002
006
059
142
041
002
240
002
144
002
201
002
172
000
002
173
045
002
144
002
176
105
196
162
162
032
141
103
169
024
141
001
208
169
023
003
141
173
073
041
228
199
196
032
073
061
002
002
059
173
141
016
002
240
007
162
059
162
048
240
032
002
060
032
002
160
060
160
048
024
141
032
208
216
194
196
169
003
141
016
208
169
000
208
141
059
000
015
016
255
076
173
060
016
002
189
240
002
060
060
027
173
015
173
006
002
039
002
008
142
016
002
144
233
007
002
015
002
173
045
165
242
025
162
033
150
248
150
242
236
074
043
226
182
093
128
192
127
232
240
110
153
061
252
162
221
021
025
102
114
122
223
191
077
046
245
046
178
253
205
032
250
179
049
104
227
105
242
062
145
251
002
032
032
248
103
169
000
141
003
208
141
169
000
002
015
104
032
169
233
003
002
173
061
063
109
024
196
002
059
031
162
002
174
022
173
031
162
060
140
201
045
002
172
026
173
014
032
50898 : 002, 160, 008, 140,060,002,070
50904 : 173, 059, 002, 172, 060, 002, 172
50910 : 074, 074, 074, 192, 008, 144, 020
50916 :002, 105, 031, 109, 045, 002, 010
50922 : 141 , 048, 002 , 041 , 224, 074, 252
50928 :074, 105, 176, 141, 003, 208, 179
50934 : 173, 048, 002, 041, 031, 010, 039
50940 : 010, 010, 105,053, 141,002,061
50946 : 208 , 169 , 000 , 105 , 000 ,133,105
50952 :097, 173, 060, 002, 010, 010, 104
50958 : 010, 105, 051, 141, 001, 208, 018
50964 : 173, 059, 002, 010, 010, 010, 028
50970 : 038, 097, 105, 024, 141, 000, 175
50976 : 208, 165, 097, 105, 000, 141, 236
50982 :016, 208, 173,048,002, 205, 178
50988 : 081 , 002 , 240 , 009 , 032 , 012 , 164
50994 : 192 , 173 , 048 , 002 , 141 , 081 , 175
51000 : 002, 076, 010, 198, 032, 047, 165
51006 : 193, 173, 060, 002, 041, 007, 026
51012 :168, 173,059,002,041,007,006
51018 : 073, 007, 170,232, 134,097,019
51024 : 056, 169, 000, 042, 202, 208, 245
51030 :252, 174,063,002, 208,048,065
51036 : 133, 097, 173, 075, 002, 208, 012
51042 : 022 , 169 , 000 , 141 , 064, 002 , 240
51048 : 141, 038, 208, 177, 253, 037, 190
51054 : 097, 208, 008, 169, 001, 141, 222
51060 :064, 002, 141, 038, 208, 165, 222
51066 : 097, 073, 255, 049, 253, 174, 255
51072 :064, 002, 240, 002, 005, 097, 026
51078 : 145, 253, 032, 012, 192, 096, 096
51084 : 1 33 , 098 , 074 , 005 , 098 , 073 , 109
51090 : 255, 049, 253, 166, 097, 202, 144
51096 : 133, 097, 173, 066, 002, 074, 185
51102 : 042, 202, 208, 252, 005, 097, 196
51108 : 145, 253, 076, 012, 192, 141, 215
51114 : 065, 002, 174, 197, 199, 221, 004
51 120 : 197 , 199 , 240 , 004 , 202 , 208 , 202
51126 : 248, 096, 202, 138, 010, 170,022
51132 : 189, 233, 199, 072, 189, 232, 022
51138 : 199, 072, 096, 034, 133, 137, 097
51144 :134, 138,077,082, 147,018,028
51150 : 145, 017, 157, 029, 070, 135, 247
51156 : 139, 049, 050, 051, 052, 019, 060
51162 : 136, 140, 033, 034, 035, 036, 120
51168 : 086, 083, 076, 024, 004, 006, 247
51174 : 131, 084, 150, 194, 128, 194, 087
51180 : 201 , 194 , 172 , 194, 227 , 194 ,138
51186 : 002. 195.068,195,073,193,200
3: High-Speed Graphics
u
u
1 '
51192 : 052 , 200 , 074 , 200 , 096 , 200 , 046
51198 :118, 200, 142, 200, 177, 200, 011
51204 :212, 200, 224, 200, 224, 200, 240 M
51210 :224, 200, 224, 200, 241, 200, 019
51216 :010, 201, 032, 201, 050, 201, 199
51222 :050, 201, 050, 201, 050,201, 007 s i
51228 :124, 201, 175, 202, 059, 203, 224 U
51234 :075, 203, 199, 203,094, 194, 234
51240 : 043, 200, 167, 193, 162, 255, 036
51246 : 154, 032, 129, 255, 076, 247, 171
51252 : 196 , 173 , 060 , 002 , 041 , 007 , 019
51258 : 133, 097, 056, 173, 060, 002, 067
51264 : 233, 008, 056, 229, 097, 141, 060
51270 : 060, 002, 076, 138, 200, 173, 207
51276 :060, 002, 041, 007, 133, 097, 160
51282 :024, 173, 060, 002, 105, 008, 198
51288 : 056, 229, 097, 141, 060, 002, 161
51294 : 076, 138, 200, 173, 059, 002, 230
51300 .-041,007,133,097,056,173,095
51306 : 059, 002, 233, 008, 056, 229, 181
51312 : 097, 141, 059, 002, 076, 138, 113
51318 : 200, 173,059,002,041,007,088
51324 : 133, 097, 024, 173, 059, 002, 100
51330 : 105, 008, 056, 229, 097, 141, 254
51336 : 059 , 002 , 104 , 104 , 076 , 091 , 060
51342 : 198, 032, 047, 193, 032, 023, 155
51348 : 193, 160, 007, 024, 173, 082, 019
51354 : 002, 101, 254, 105, 143, 133, 124
51360 :252, 165, 253, 133, 251, 177, 111
51366 : 251, 145, 253, 136, 016, 249, 192
51372 :032, 035, 193, 076, 012, 192, 200
51378 : 169, 016, 141, 063, 002, 169, 226
51384 : 001 , 141 , 029 , 208 , 032 , 012 , 095
51390 : 192, 032, 094, 193, 169, 050, 152
51396 : 141 , 065 , 002 , 032 , 225 , 200 , 093
51402 : 173, 059, 002, 041, 254, 141, 104
51408 : 059, 002, 076, 138, 200, 169, 084
51414 : 000, 141, 063, 002, 141, 029, 078
51420 : 208 , 032 , 012 , 192 , 096 , 056 , 048
51426 : 173,065,002, 233,049, 141, 121
51432 : 066 , 002 , 170 , 189 , 003 , 192 , 086
51438 :141, 038, 208, 096, 173, 059, 185 ! '
51444 :002, 013, 060, 002, 208, 003, 020
51450 : 141, 045, 002, 169, 000, 141, 236
51456 :059 , 002 , 141 , 060 , 002 , 032 , 040
51462 : 012, 192, 076, 138, 200, 032, 144
51468 :074, 193, 032, 074, 193, 032, 098
51474 :047, 193, 160, 000, 177, 253, 080
51480 : 153 , 067 , 002 , 200, 192 , 008 , 134
u
126
U
n
n
High-Speed Graphics: 3
i \
51486 : 208, 246, 096, 032, 047, 193 ,084
_ 51492 : 160, 000, 185, 067, 002, 145, 083
I I 51498 :253, 200, 192, 008, 208, 246, 125
51504 :076, 012, 192, 169, 082, 160, 227
51510 : 196, 032, 145, 196, 032, 228, 115
51516 :255, 240, 251, 162, 000, 221, 165
I I 51522 :218, 232, 240, 008, 232, 224, 196
51528 : 016 , 208 , 246 , 076 , 141 , 196 , 187
51534 :056, 173,065,002, 233,033, 128
51540 : 168, 138, 153, 003, 192, 192, 162
51546 : 003, 240, 010, 192, 000, 240, 007
51552 :022, 153, 033, 208, 076, 119, 195
51558 : 201, 174, 063, 002, 240, 002, 016
51564 : 041, 007, 141, 058, 002, 153, 254
51570 : 003, 192, 032, 094, 193, 032, 148
51576 :012 , 192 , 076 , 141 , 196 , 169 , 138
51582 : 161, 160, 201, 032, 145, 196, 253
51588 : 032, 228, 255, 056, 233, 048, 216
51594 : 048, 248, 201, 010, 176, 244, 041
51600 : 133 , 097 , 056 , 169 , 009 , 229 , 069
51606 : 097, 010, 010, 010, 010, 141, 172
51612 :076, 002, 076, 141, 196, 067, 202
51618 : 085, 082, 083, 079, 082, 032, 093
51624 : 086 , 069 , 076 , 079 , 067 , 073 , 106
51630 : 084, 089, 032, 040, 048, 045, 000
51636 :057 , 041 , 063 , 095 , 160 , 000 , 084
51642 : 140, 078, 002, 169, 164, 032, 003
51648 : 210, 255, 169, 157, 032, 210, 201
51654 : 255, 032, 228, 255, 240, 251, 179
51660 : 172, 078, 002, 133, 097, 169, 087
51666 : 032, 032, 210, 255, 169, 157, 041
51672 :032, 210, 255, 165, 097, 201, 152
51678 :013, 240,039, 201,020, 208, 175
51684 : 013 , 192 , 000 , 240 , 209 , 136 , 250
51690 : 169, 157,032, 210, 255,076, 109
51696 : 186 , 201 , 041 , 127 , 201 , 032 , 004
51702 : 144, 194, 192, 020, 240, 190, 202
r~l 51708 :165, 097, 153, 000, 002, 032, 189
' 1 51714 :210, 255, 200, 076, 186, 201, 106
51720 : 169, 095, 153, 000, 002, 152, 067
_ 51726 :096,032,231,255,169,054,083
ij 51732 :160, 196, 032, 145, 196, 032, 013
51738 : 228, 255, 240, 251, 162, 001, 139
51744 : 201 , 084 , 240 , 011 , 162 , 008 , 226
ft 51750 i 201, 068, 240, 005, 104, 104, 248
1 1 51756 :076, 141, 196, 141, 077, 002, 165
51762 : 160, 001, 169, 001, 032, 186, 087
„ 51768 :255, 169, 072, 160, 196, 032, 172
; < 51774 :196, 196, 032, 184, 201, 208, 055
127
3: High-Speed Graphics
u
u
007,173,077,002,
208,237,173,077,
068,208,066,169,
020,002,169,048,
002,169,058,141,
160,000,185,000,
023,002,200,204,
208,244,169,044,
002,169,080,153,
173,065,002,201,
012,169,044,153,
169,087,153,026,
200,200,200,200,
076,163,202,160,
000,002,153,020,
204,078,002,208,
162,020,160,002,
255,169,160,133,
032,015,202,032,
169,000,133,253,
169,112,133,252,
160,119,169,251,
255,176,011,032,
208,006,032,114,
141,196,032,114,
231,255,173,077,
068,240,015,169,
196,032,145,196,
255,240,251,076,
169,000,032,189,
015,162,008,160,
186,255,032,192,
015,032,198,255,
032,207,255,201,
007,153,000,002,
010,203,169,095,
002,032,204,255,
160,002,032,145,
015,032,201,255,
032,210,255,169,
210,255,032,231,
234,202,032,015,
082,203,169,000,
255,176,141,076,
169,004,141,136,
120,169,000,141,
169,255,141,013,
049,141,020,003,
141,021,003,169,
201,084,100
002,201,204
064,141,028
141,021,231
022,002,230
002,153,086
078,002,101
153,023,183
024,002,034
083,208,086
025,002,021
002,200,003
200,200,060
000,185,164
002,200,017
244,152,022
032,189,217
178,096,137
082,203,230
133,251,097
162,255,247
032,216,117
183,255,088
203,076,077
203,032,162
002,201,133
035,160,143
032,228,035
141,196,115
255,169,032
015,032,128
255,162,056
160,000,152
013,240,190
200,076,198
153,000,140
169,000,178
196,162,219
169,073,017
013,032,245
255,076,087
202,032,007
032,213,251
114,203,011
002,000,016
026,208,234
220,169,031
169,234,198
000,141,063
LJ
U
U
i 1
128
! I
52074 :021,208,169,147,088,076,047
52080 : 210, 255, 032, 085, 195, 169, 034
52086 : 003, 141 ,021, 208, 032, 012, 023
52092 : 192, 032 ,094,193,076,141,084
52098 : 196, 248, 169, 000, 141, 000, 116
52104 : 001, 141, 001, 001, 224, 000, 248
52110 : 240, 021, 202, 024, 173, 000, 034
52116 :001 , 105 , 001 , 141 , 000 , 001 , 141
52122 : 173, 001, 001, 105, 000, 141, 063
52128 :001, 001, 076, 140, 203, 216, 029
52134 : 173, 001, 001, 009, 048, 141, 027
52140 : 002, 001, 173,000,001,041, 134
52146 : 240, 074, 074, 074, 074, 009, 211
52152 :048, 141, 001, 001, 173, 000, 036
52158 : 001, 041, 015, 009, 048, 141, 189
52164 :000, 001, 096, 096, 056, 165, 098
52170 : 045, 233, 002, 133, 045, 165, 057
52176 :046 , 233 , 000 , 133 , 046 , 169 , 067
52182 :024, 133, 057, 169, 246, 133, 208
52188 :058, 169,000, 141,079,002, 157
52194 : 133, 251, 133, 253, 169, 112, 253
52200 : 133, 254, 173, 082, 002, 133, 241
52206 : 252,032,023, 193, 160,000, 130
52212 : 177, 251, 209, 253, 208, 062, 124
52218 : 200, 192, 008, 208, 245, 238, 061
52224 :079, 002, 024, 165, 253, 105, 116
52230 : 008, 133, 253, 133, 251, 165, 181
52236 : 254, 105, 000, 133, 254, 109, 099
52242 : 082, 002, 105, 143, 133, 252, 223
52248 : 173 , 079, 002 , 208 , 213 , 169 , 100
52254 : 000, 168, 145 , 045 , 200, 145 , 221
52260 :045, 024, 165, 045, 105,002,166
52266 -.133,045,165,046,105,000,024
52272 : 133, 046, 032, 035, 193, 076, 051
52278 : 051, 165, 160, 000, 024, 165, 107
52284 : 045, 105, 041, 145, 045, 200,129
52290 : 165, 046, 105, 000, 145, 045, 060
52296 : 200, 165 , 057 , 145 , 045 , 200 , 116
52302 : 165, 058, 145, 045, 200, 169, 092
52308 : 131, 145, 045, 174, 079, 002, 148
52314 :032, 131, 203, 200, 173,002,063
52320 : 001, 145, 045, 200, 173, 001, 149
52326 : 001, 145, 045, 200, 173, 000,154
52332 :001, 145,045, 200,132,097,216
52338 : 160, 000, 132, 098, 177, 253, 166
52344 : 170, 032, 131, 203, 164, 097, 149
52350 : 169,044, 145, 045, 200, 173, 134
52356 :002, 001, 145, 045, 173, 001, 243
52362 : 001. 200. 145. 045, 173, 000, 190
3: High-Speed Graphics
52368 : 001, 200, 145, 045, 200, 132 ,099
52374 : 097 , 164, 098, 200 , 192 , 008, 141
52380 : 208 , 214 , 164 , 097 , 169 , 000 , 240
52386 : 145, 045, 160, 000, 177, 045, 222
52392 :072, 200, 177, 045, 133, 046, 073
52398 : 104, 133, 045, 230, 057, 208, 183
52404 : 002 , 230 , 058 , 076 , 255 , 203 , 236
130
Charles Brannon
Sprite Magic:
An All-Machine-Language
Sprite Editor
Sprites make animation on What Is a Sprite Editor?
the 64 fun and easy to program. Most of what you've read
But actually drawing and about sprites covers how to
creating sprites with graph program them: setting them
paper can be tedious. "Sprite U P> protecting memory,
Magic" simplifies their creation, movmg and animating them,
and lets you concentrate on s^SfdeTn^u^Tali
the artistic aspects of sprite ^ ^" e yo e u S1§n 1S USUa 7
design. You can even A sprite is defined by
animate mtntmovies! 63 binary num bers. The one
bits (on) represent solid pixels. Zeros (off) represent blank areas,
through which the screen background is visible. Normally, you sketch
a sprite on a grid 24 squares across and 21 squares high. This is three
bytes per row (8 bits * 3 bytes = 24 bits) and 21 rows of bytes (3 * 21 = 63
bytes). But after you've drawn the sprite, you have to convert the
squares into binary, and then into decimal so that you can put the
numbers in DATA statements.
There are utility programs that will do the conversion for you,
even editors that let you clear and set squares with a joystick. Since
you're using a computer, other functions can be supported to let you
clear, invert, reflect, reverse, shift, and test out your sprite. The more
work the computer does, the less you have to think in terms of binary
numbers. Having used many sprite editors, I craved a utility that
would make sprites easy to draw and fun to use. Although there are
many good sprite editors available for the 64, none had all the features
I wanted. So I wrote "Sprite Magic."
Sprite Magic includes the best features of most sprite editors,
including true multicolor mode, and pulls it off with the speed and
power of an all machine language program. Sprite Magic's style (and
even some of the coding) came from "Ultrafont + ," an all machine
language character editor also in this book. As a matter of fact, many
of the commands are the same, which lets you get up to speed quickly .
If you've learned how to use Ultrafont + , it won't take much to
become comfortable with Sprite Magic.
131
3: High-Speed Graphics
Typing It In
Since Sprite Magic is an all machine language program, you cannot
enter it as you do a BASIC program. Machine language is basically a
bunch of numbers; the numbers make no sense in themselves. Only
the 6510 microprocessor in your machine can interpret and execute
these numbers. Since typing in numbers is no fun, we've tried to make
it as painless as possible with MLX, the Machine Language Editor.
You'll find MLX, and the explanation of its use and commands, in
Appendix D of this book. If you haven't already typed in MLX, do
so before you try to enter Sprite Magic. MLX is used for two other
machine language programs in this book, as well as in COMPUTE!
magazine and COMPUTEI's Gazette, so save it for future use.
After you've typed in MLX, RUN it and answer the prompts of
Starting Address and Ending Address with 49152 and 51821, respec-
tively. You'll then be ready to start typing in Sprite Magic. Enter each
line from the listing at the end of this article. The last number in
each line is a checksum, so type it carefully. If the checksum you've
typed matches the checksum computed from the line you typed, a
pleasant bell tone tells you you've typed the line correctly. If the num-
ber doesn't match, a buzzer warns you to reenter the line. This way,
you should be able to type in Sprite Magic correctly the first time.
Assuming you've typed and saved Sprite Magic, here's how you
get it up and running. If you used the filename "SPRITE MAGIC", type:
LOAD "SPRITE MAGIC",8,1 (for disk)
or
LOAD "SPRITE MAGIC", 1,1 (for tape)
Be sure to add the (,1) to the end. After the computer comes back with
the READY message, type NEW and press RETURN. This resets some
important memory locations, but leaves Sprite Magic in its protected
cubbyhole at S5C000.
Doodle!
Activate Sprite Magic with SYS 49152. Instantly, the main screen
should appear, with a large 24 x 21 grid. The grid is a blowup of the
sprite you're editing. The actual sprite will be seen to the right of the
grid. The flashing square within the large grid is your cursor. You
move the cursor with either the cursor keys on the keyboard, or
with a joystick plugged into port 2 . To light up a blank spot (in other
words, to turn that pixel on), press either the space bar or the joystick
fire button. If the square is already lit, it will turn dark. This signifies
that the pixel has been turned off. The button or space bar thus tog-
gles points on or off. You can draw your sprite quite easily in this
132
High-Speed Graphics: 3
manner. One fine point: With the joystick, you can hold down the
fire button and move the cursor. If the first point you change was
set, the fire button will continue to set points as you move the joy-
stick, regardless of the other points' original state. If the first point
you change was empty, you can hold down the fire button and move
about, clearing anything the cursor passes over. Notice how any
changes are immediately visible in the actual sprite.
If you've just entered Sprite Magic, the grid is probably full of
garbage pixels. To clear out the grid for a new picture, press SHIFT-
CLR/HOME. You now have an empty area (a fresh canvas, so to speak)
to draw upon. You can press CLR/HOME without holding down
SHIFT to home the cursor to the upper left-hand corner of the grid.
, Does the cursor move too slow or too fast? To change the velocity
(speed) of the cursor, press V. Answer the prompt with a number key
from (slow) to 9 (very fast).
Shift, Expansion, and Symmetry
Sometimes when you're drawing, it's necessary to reposition the
shape within the grid. The first two function keys let you shift the
sprite shape around within the grid. If you shift something out of the
grid, it wraps around to the opposite side. The f 1 Jkey shifts right, f 3
shifts down. Use the SHIFT key along with the function key to move
in the opposite direction: f2 moves the sprite shape left; f4, up.
After you've drawn something, press the F key. Instantly, the
sprite is flipped upside down. Press it again to flip it back over.
Remember F as the command for Flip. Now try M, for Mirror. The
shape you've drawn is mirrored left to right. Of course, if you've
drawn something symmetrical, you may not see any change.
Now try CTRL-R or CTRL-9- The sprite will become reversed.
Every square that was on is now turned off, and vice versa.
A sprite can also be expanded or contracted either horizontally
or vertically, or both horizontally and vertically. The X and Y keys
on the keyboard let you do this. Press X to switch from wide to nar-
row, or vice versa. Press Y to switch from tall to short, or vice versa.
The main grid will not change size or proportion (there's not enough
room on the screen).
An unusual command is Symmetry. I added this command after
some suggestions that many shapes are symmetrical from left to
right, as if a mirror were put in the middle of the grid. To enter the
Symmetry mode, press the back arrow key (found in the upper left-
hand corner of the keyboard). Now, every square drawn on one side
will be instantly mirrored to the left. Blank squares are not copied
133
3: High-Speed Graphics
over, though, so you cannot erase in this mode. This command is not
only quite useful, but also a great deal of fun to play with. To return
to normal editing, press the back arrow key again.
Notice the number in the upper right-hand corner of the screen.
This is the sprite page number, which can range from to 2 5 5 . You
start out at the top of the sprite memory. The + and - keys are used
to go forward or backward through sprite shapes. Press the minus
key and see how you now have a new shape in the grid. There is a
limit to how far back you can go. If you have no BASIC program in
memory, you can step back to sprite page number 36. However, char-
acter information resides in sprite pages below 128. You can still
clear the page and draw a sprite shape on pages below 128, but it
won't really register. To be safe, use only the sprite pages from 128
on up. If you have a program in memory, Sprite Magic will not let you
step back past its end. This protects your program from being acci-
dentally overwritten by a sprite shape. If you want maximum space
available for sprite shapes, be sure to NEW out any BASIC program
before you SYS 49152. You'll sometimes want to keep a program in
memory, however. We'll show you why a bit later.
Programming note: The sprite page number, when multiplied by
64, gives you the starting memory location for the 63 numbers
representing the sprite.
Put It in the Buffer
You might use Flip to design two views of a shape, such as a spaceship
pointing in two directions. Draw one freehand, then do the other
with Flip. Mirror can be used to design separate left and right views
as well. But what you first need is a way to copy the original shape
to another sprite area. One way to do this is to copy the sprite shape
to an area of memory (a buffer). You can use + or - to step to
another sprite page, then copy the buffer to the sprite. This, if you
remember, is the way you copy characters with Ultrafont + . The
same keys are used in Sprite Magic. Press f7 to copy the sprite to the
buffer. The grid flashes to affirm this. Then go to the sprite page
where you want to put the copy and press f8 (SHIFT-f7). The shape
in the buffer replaces any shape already in the sprite grid. You can
also use the buffer as a fail-safe device. Before modifying an existing
sprite, press f 7 to save it in the buffer. Then, if you mangle the sprite,
or accidentally erase it, you can recall the previous shape from
the buffer.
134
High-Speed Graphics: 3
Computer Disney?
The buffer is also useful for animation. Since you can change sprite
pages so easily, you can also use Sprite Magic as an animation design
tool. Cartoons make only minor changes between frames. Too much
change makes the animation jerky. So put the first frame into the
buffer, copy it to the next area, then make a change. Put the new
image into the buffer, copy it again to a new area, then make another
small change. Continue in this fashion as you build up a whole series
of frames. Put different but similar shapes on adjacent pages, then hold
down plus or minus to step through the shapes. As with cartoon
animation, you will get the illusion of motion. Use a cursor velocity
of 9 for maximum speed. Even if you don't care to program sprites,
Sprite Magic is a fun tool for making moving cartoons.
A Bit of Color
The normal drawing mode lets you set or clear points, but in only one
color. If you're willing to give up half as many horizontal points, you
can have four colors to work with. Multicolor mode lets any square
be one of four colors, but gives you only 12 pixels across instead of
24. This is because two dots are grouped together to give four com-
binations. The colors come from four memory locations:
Pattern Color location
00 53281 Background color register
01 53285 Sprite multicolor register
10 53287- Sprite color registers
53294
11 53286 Sprite multicolor register 1
There are two multicolor sprite registers, which are shared
between all sprites (in programming, but not in Sprite Magic, you can
have eight sprites on the screen at the same time). The bit pattern
marked 10 is unique to each sprite and comes from that sprite's own
color register. 00 is blank, and whatever is underneath the sprite
shape will show through.
The reason for this sojourn into bits and addresses is that only
the 10 bit pattern has a unique color for that sprite. If you're design-
ing several sprites for a game, remember that anything drawn in that
color can be changed individually for each sprite. Squares drawn
with bit pattern 01 or 11 will be colored from two locations shared
by all sprites.
Many sprite editors let you see how the sprite would look in
multicolor, but you still have to pair up the pixels yourself and keep
135
3: High-Speed Graphics
track of binary bit pairs. No fun! Instead, Sprite Magic offers a multi-
color mode. When you press f5, the screen instantly changes. Each
square in the grid is now rectangular, two squares wide. The cursor
has also been enlarged, and can be moved about as before in the new
grid. But the way you set and clear points has been changed, since
you are now working with four colors.
Multicolor Palette
The fire button or the space bar always sets a point, but you have to
tell Sprite Magic which color you are currently drawing in. The
number keys 1 to 4 select the drawing color. The number you press
is one number higher than the binary value of the bit-pairs in the
table above. The 1 key, for instance, chooses the 00 bit-pair, which
represents the background color. In practice, you are choosing from
a palette of four colors. The 1 key is normally used when you want
to erase.
When you press a number key from 1 to 4, the border color
changes to remind you which color you're drawing with. If you
want to change one of the four colors, hold down SHIFT while you
type the number. The prompt ENTER COLOR KEY appears. Now
you have to enter another key combination. Press CTRL and one of
the number keys from 1 to 8, or hold down the Commodore key
and one of the number keys from 1 to 8. These are the same key com-
binations you use to change the text color in BASIC. You can also
change the screen background color by pressing the letter B on the
keyboard until the color you want appears.
Some Sprite Magic commands act strangely in multicolor mode.
For example, a shift left or shift right (done with the f 1 or f2 key
respectively) moves the sprite over by only one bit, which changes
the color assignments. In general, you must press f 1 or f2 twice to
preserve the same colors. Pressing the M key (for Mirror) reverses the
bit-pairs, so that every 01 becomes a 10. The effect is that colors 2
and 3 are exchanged. The R key (Reverse) also inverts the bits, so that
01 becomes 10, 10 becomes 01, 00 becomes 11, and 11 becomes 00.
Colors 2 and 3 are switched, as well as colors 1 and 4. The Symmetry
command (back arrow) also does not work in multicolor mode.
If you want to go back to normal (nonmulticolor) mode, press
the f6 key (SHIFT-f5). There's nothing to prevent you from designing
both normal and multicolor sprites on different pages.
If you changed colors in the multicolor mode, some of the colors
in the normal mode may have been changed. You can alter these
colors as in multicolor mode. Press SHIFT-1 to change the color of
136
High-Speed Graphics: 3
the empty pixels, and SHIFT-2 to alter the color of the on pixels.
(You'll be prompted to press a color key after each SHIFT-1 or
SHIFT-2 combination.)
Action!
If you want to try out your sprite in action, press J (for Joystick). You
can now move the actual sprite around with the joystick. The speed
of movement depends on the current cursor velocity. When you've
finished putting your sprite through its paces, press the fire button
to return to Sprite Magic. Also, if you want to test the animation while
you are moving about, hold down the SHIFT key to step forward, or
the Commodore key to step backward. You can lock the SHIFT key
to keep the animation happening while you move around.
Saving Your Sprites
After all your work, you surely want to save your creations on tape
or disk for future use. You can save an individual shape, or all the
sprites. Press S (for Save), then either D (Disk) or T (Tape). Next, enter
the filename. You'll be asked if you want to "Save all from here?" If
you press N for No, only the current sprite you are working on is
saved. If you press Y for Yes, every sprite from the current to sprite
255 will be saved. Thus, if you want to save a range of sprites, be sure
to use the minus key to step back to the first sprite you want saved.
To recall your sprites, press L. The Load command loads every-
thing that was saved. If you're loading in more than one sprite, be
sure you step backward far enough with the minus key so that all the
sprites will fit between the current sprite and sprite 255. The sprites
load starting at the current sprite page number. After you press L,
enter T or D for Tape or Disk.
Let There Be DATA
If you're a programmer, you're probably more interested in DATA
statements. That way, you can use BASIC to READ and POKE the
numbers into memory. If you have some kind of DATAmaker, you can
run it on the memory used by the sprite in Sprite Magic (again, the
memory location is the sprite number times 64). But Sprite Magic
has a special DATAmaker of its own. It's similar to the Create DATA
option in Ultrafont + , but it's been enhanced.
Press CTRL-D to create a series of DATA statements from the
current sprite in memory. Just tap the key, or you'll get hundreds of
DATA statements as the key repeats. Sprite Magic will create eight
DATA statements, with eight bytes per line. The last byte is not strictly
used. Sprite shapes are made from 63 bytes, but the sprite areas are
137
3: High-Speed Graphics
padded out so they will conveniently fall in 64-byte ranges. To create
DATA statements for another sprite, use the + or - key to move to
the correct sprite page, then press CTRL-D again.
If you have a program already in memory, the DATA statements
are appended to the end of the program, starting with the next
available line number. To add DATA statements to an existing program,
then, first load Sprite Magic. Type NEW. Load your BASIC program,
and SYS 49152 to enter Sprite Magic. You can then load in sprite
shapes and use CTRL-D to add those DATA statements to the end of
the BASIC program in memory.
You can check to see that these DATA statements were added by
exiting Sprite Magic (press CTRL-X) and typing LIST. Your program
should have eight new DATA lines for each sprite pattern. If there was
no program in memory, the DATA statements form a program all
their own, starting with line 1. If you want, you can save just the DATA
statements to tape or disk, using the normal SAVE command.
To exit Sprite Magic and return to BASIC, press CTRL-X. You can
also use RUN/STOP-RESTORE.
We're quite pleased that we can offer you such a powerful , easy-
to-use utility. We also hope that it encourages more beginning pro-
grammers to learn about sprites. Now that you have a sprite editor,
how about using it to write a fantastic game?
138
High-Speed Graphics: 3
Quick Reference Chart: Sprite Magic
1
B:
F:
J:
L:
M:
S:
V:
X:
Y:
CTRL-D:
CTRL-R or CTRL-9:
CTRL-X:
+
CLR/HOME:
SHIFT-CLR/HOME:
Space bar or
fire button:
CRSR keys or joy-
stick in port 2:
Back arrow:
Keys 1-4:
SHIFT 1-4:
fl:
f2
f3
f4
f5
f6
f7:
f8
Cycle through background colors
Flip sprite upside down
Move sprite with joystick. Press button
when done.
Load sprites from tape or disk
Mirror sprite from left to right
Save sprite(s) to tape or disk
Set cursor velocity
Toggle X expansion on/off
Toggle Y expansion on/off
Create DATA statements
Reverse sprite
Exit to BASIC
Next sprite page
Previous sprite page
Home cursor
Erase grid
Set/clear points
Move cursor
Symmetry mode (only in normal mode)
Select drawing color for multicolor
mode
Change a drawing color
Shift right
Shift left
Shift down
Shift up
Multicolor mode
Normal mode
Store sprite to buffer
Recall sprite from buffer
139
3: High-Speed Graphics
Sprite Magic
Be sure to read "Using the Machine Language Editor: MLX, ' 'Appendix D, before typing in
this program.
49152
49158
49164
49170
49176
49182
49188
49194
49200
49206
49212
49218
49224
49230
49236
49242
49248
49254
49260
49266
49272
49278
49284
49290
49296
49302
49308
49314
49320
49326
49332
49338
49344
49350
49356
49362
49368
49374
49380
49386
49392
49398
49404
49410
49416
49422
:076,
:004,
:133,
:133,
:169,
:003,
:177,
:240,
:207,
:176,
:167,
:192,
:208,
:008,
:252,
:212,
:002,
:173,
:165,
:133,
:133,
:206,
:240,
:134,
:002,
:006,
:042,
:200,
:189,
:145,
:215,
:133,
:253,
:253,
:254,
:253,
:254,
:000,
:253,
:096,
:136,
:200,
:040,
:202,
:208,
:160,
032,195,
032,184,
252,169,
167,169,
021,141,
141,041,
253,170,
003,076,
145,251,
008,173,
076,069,
145,167,
221,024,
133,251,
105,000,
133,168,
230,254,
041,002,
251,105,
167,165,
252,105,
040 , 002 ,
003,076,
097,169,
006,097,
097,046,
002,169,
169,247,
003,192,
167,200,
076,074,
254,173,
006,253,
038,254,
006,253,
038,254,
096,032,
177,253,
200,192,
032,184,
136,177,
200, 162,
042,008,
208,245,
230,096,
000, 200,
000,001
192,169
000,133
216,133
040,002
002,160
173,048
138,192
138,010
003,192
192,173
200,192
165,251
133,167
133,252
230,253
206,041
208, 183
016,133
252,105
212,133
173,040
029,192
000,141
046,042
042,002
207,145
145,251
145,167
192,008
192,169
043,002
038,254
006,253
038,254
006,253
184,192
073,255
064,208
192,160
253,010
003,177
145,253
040,192
032,184
200,177
,003,051
,004,079
,251,182
,168,236
,169,054
,000,121
,002,091
,169,092
,170,201
,145,239
,004,229
,008,202
,105,022
,165,167
,105,163
,208,014
,002,063
,024,221
,251,005
,000,168
,168,099
,002,077
,096,000
,042,209
,002,083
, 174,005
,251,204
,136,030
,200,040
,208,070
,000,138
,133,156
,006,234
,038,016
,006,247
,038,028
,160,110
,145,101
,245,110
,062,192
,008,192
,253,217
,136,108
,255,120
,192,182
,253,236
140
49428 :074, 008, 136, 136, 162, 003, 027
49434 : 177, 253, 040, 106, 008, 145, 243
49440 : 253 , 200 , 202 , 208 , 245 , 040 , 156
49446 : 192 , 063 , 208 , 230 , 096 , 032 , 091
49452 :184, 192, 160, 000, 177, 253, 242
49458 : 153 , 173 , 202 , 200, 192 , 003 , 205
49464 : 208 , 246 , 177 , 253 , 136 , 136 , 188
49470 : 136, 145, 253, 200, 200, 200, 172
49476 : 200 , 192 ,063 , 208, 241 , 162 ,110
49482 : 000 , 160 , 060 , 189 , 173 , 202 , 090
49488 : 145, 253, 200, 232, 224, 003, 113
49494 :208, 245, 096, 032, 184, 192,019
49500 : 160, 060, 162, 000, 177, 253, 136
49506 : 157, 173, 202, 200, 232, 224, 006
49512 :003 , 208, 245 , 160 , 060, 177 , 189
49518 : 253 , 200, 200 , 200, 145 , 253 , 081
49524 : 136, 136, 136, 136, 016, 243, 151
49530 : 160 , 000 , 185 , 173 , 202 , 145 ,219
49536 :253, 200, 192, 003, 208, 246, 206
49542 :096, 032, 184,192,160,000,030
49548 : 152, 170, 232, 232, 169, 003, 074
49554 : 133, 097, 169, 008, 141, 055, 237
49560 :002, 177, 253, 074, 145, 253, 032
49566 :062, 173, 202, 206, 055, 002, 090
49572 : 1 73 , 05 5 , 002 , 208 , 240 , 200 , 018
49578 : 202, 198,097,165,097,208,113
49584 : 227, 192, 063, 144, 215, 160, 153
49590 :000, 185,173,202,145,253,116
49596 : 200, 192, 063, 208, 246, 096, 169
49602 : 169, 147, 032, 210, 255, 173,156
49608 :000 , 220 , 133 , 097 , 041 , 015 , 194
49614 :073, 015, 170, 173, 000, 208, 077
49620 : 024, 125, 066, 194, 141, 000, 250
49626 : 208, 173, 016, 208, 125, 077, 001
49632 : 194, 141, 016, 208, 173, 001, 189
49638 : 208, 024, 125, 088, 194, 141, 242
49644 : 001, 208, 032, 018, 195, 173, 095
49650 : 141 , 002 , 041 , 001 , 024 , 109 , 048
496 56 : 248 , 007 , 141 , 248 , 007 , 173 , 048
49662 : 141 , 002 , 041 , 002 , 074, 073 , 075
49668 :255 , 056 , 109 , 248 , 007 , 141 , 052
49674 : 248 , 007 , 165 , 097 , 041 , 016 ,072
49680 : 208, 181, 173, 000, 220, 041, 071
49686 : 016, 240, 249, 173, 043, 002, 233
49692 :141, 248, 007, 032, 059, 196, 199
49698 : 169, 255, 141,000, 208, 169, 208
49704 :000 , 141 , 016 , 208 , 169 , 128 , 190
49710 : 141, 001, 208, 076, 177, 194, 075
49716 :032, 184, 192, 160, 000, 152, 004
3: High-Speed Graphics
49722 : 145, 253, 200, 192,063,208,095
49728 s 249 , 096 , 000 , 000 , 000 , 000 ,153
49734 : 255, 255, 255, 000, 001, 001, 069
49740 : 001 , 000 , 000 , 000 , 000 , 255 , 076
49746 : 255 , 255 , 000 , 000, 000 , 000 , 080
49752 :000, 255, 001, 000, 000, 255, 087
49758 : 001, 000, 000, 255, 001, 018, 113
49764 :083 , 080 , 082 ,073 , 084 , 069 , 059
49770. :032, 077, 065, 071, 073, 067, 235
49776 :146, 095, 069, 082, 082, 079, 153
49782 : 082 , 032 , 079 , 078 , 032 , 083 , 248
49788 :065 , 086 , 069 , 047 , 076 , 079 , 034
49794 :065, 068, 095, 018, 084, 146, 094
49800 : 065 , 080 , 069 , 032 , 079 , 082 , 031
49806 : 032 , 018 , 068 , 146 , 073 , 083 , 050
49812 :075 , 063 , 095 , 070 , 073 , 076 , 088
49818 : 069 , 078 , 065 , 077 , 069 , 058 , 058
49824 : 095 ,069 , 078 , 084 , 069 , 082 ,125
49830 : 032 , 067 , 079 , 076 , 079 , 082 , 069
49836 :032, 075, 069, 089, 095, 169, 189
49842 :099, 160, 194, 133, 251, 132, 123
49848 :252, 160, 040, 169, 032, 153, 222
49854 : 191, 007, 136, 208, 250, 177, 135
49860 : 251 , 200 , 201 , 095 , 208 , 249 ,120
49866 : 136 , 132 , 097 , 152 , 074 , 073 , 098
49872 : 255 ,056 , 105 , 020 , 168 , 162 , 206
49878 : 024, 024, 032, 240, 255, 169, 190
49884 : 146 , 032 , 210 , 255 , 160 , 000 , 255
49890 : 177, 251,032, 210, 255, 200,071
49896 : 196 , 097 , 144 , 246 , 096 , 133 , 120
49902 : 251, 132, 252, 160, 040, 169, 218
49908 .-032,153, 191 , 007 , 136 , 208 , 203
49914 8 250,162,024,160,000,024,102
49920 : 032, 240, 255, 160, 000, 177, 096
49926 : 251 , 201 , 095 , 240 , 006 , 032 , 063
49932 :210, 255, 200, 208, 244, 096, 201
49938 : 174, 053, 002, 240, 008, 160, 143
49944 : 000 , 200 , 208 , 253 , 202 , 208 , 071
49950 : 250 , 096 , 169 , 147 , 032 , 210 , 166
49956 :255, 169, 000, 141, 134, 002, 225
49962 : 141 , 056 , 002 , 169 , 008 , 032 , 194
49968 :210, 255, 169, 128, 141, 138, 065
49974 : 002 , 169 , 048 , 141 , 053 , 002 , 213
49980 1169,255,141,043,002,169,071
49986 : 000 , 141 , 048 , 002 , 173 , 006 , 180
49992 :192 , 141 , 038 , 208 , 173 , 004 , 060
49998 .-192,141,037,208,141,039,068
50004 : 208, 032, 007, 192, 169, 255, 179
50010 s 141 , 000 , 208 , 169 , 1 28 , 141 , 109
142
High-Speed Graphics: 3
50016 :001 , 208 , 173 , 043 , 002 , 141 ,152
50022 : 248 , 007 , 169 , 001 , 141 , 021 , 177
50028 :208, 169, 000, 141, 028 ,208, 094
50034 : 169, 012, 141, 033, 208, 141, 050
50040 : 032, 208, 141, 044, 002, 141, 176
50046 : 045, 002, 032, 177,194,032,096
50052 :059,196,032,007,192,032,138
50058 :030, 196, 173,000,220,072,061
50064 :041, 015, 073, 015, 141, 046, 219
50070 : 002 , 104 , 041 , 016 , 141 , 047 , 245
50076 :002, 032, 228,255,240,006,151
50082 : 032, 208, 196, 076, 134, 195, 235
50088 :032, 018, 195,173,047,002,123
50094 : 208, 003, 032, 089, 196, 032, 222
50100 : 030 , 196 , 173 , 047 , 002 , 073 , 189
50106 : 016, 141, 052, 002, 173,046,104
50112 :002, 240, 195, 174, 046, 002, 083
50118 : 189,066, 194, 172,048,002,101
50124 : 240, 001, 010, 024, 109, 044, 120
50130 :002, 141, 044, 002, 024, 173,084
50136 :045, 002, 125, 088, 194, 141, 043
50142 : 045, 002, 174,044,002,016,249
50148 :017 , 162 , 000 , 142 , 044 , 002 , 083
50154 :162, 023, 173,048,002,240,114
50160 : 002, 162, 022, 142, 044, 002, 102
50166 : 174 , 044 , 002 , 224, 024, 144 , 090
50172 :005, 162, 000, 142, 044, 002, 095
50178 : 172 , 045 , 002 , 016 , 005 , 160 , 146
50184 :020, 140, 045, 002, 172, 045, 176
50190 : 002, 192, 021, 144, 005, 160,026
501 96 : 000 , 140 , 045 , 002 , 032 , 030 , 01 3
50202 : 196 , 076 , 134 , 195 , 174 , 045 , 078
50208 :002 , 172 , 044 , 002 ,032 , 240 , 012
50214 : 255, 164,211,173,048,002,123
50220 : 208 , 005 , 169 , 032 , 145 , 209 , 044
50226 :096, 169, 032, 145, 209, 200, 133
50232 : 145 , 209 , 096 , 162 , 000 , 160 , 060
50238 :030, 024, 032, 240, 255, 169, 044
50244 :018, 032, 210, 255, 174, 043, 032
50250 : 002 , 142 , 248 , 007 , 169 , 000 ,130
50256 :032, 205, 189, 169, 032, 032, 227
50262 : 210, 255, 096, 032, 184, 192, 031
50268 :173, 045, 002, 010, 109, 045, 220
50274 :002, 133,097, 173,044,002,037
50280 :074,074,074,024,101,097,036
50286 : 168 , 173 , 044 , 002 , 041 , 007 , 033
50292 :073, 007, 170, 232, 134, 097, 061
50298 : 056 , 169, 000 , 042 , 202 , 208 , 031
50304 : 252, 174, 048, 002, 208, 047, 091
143
3: High-Speed Graphics
50310 : 133, 097, 173, 052, 002, 208, 031
50316 5 016,169, 000 , 141 , 049 , 002 , 005
50322 : 177, 253, 037, 097, 208, 005, 155
50328 : 169, 001, 141, 049, 002, 165, 167
50334 : 097, 073, 255, 049, 253, 174,035
50340 1049,002,240,002,005,097,047
50346 : 145 , 253 , 173 , 056 , 002 , 240, 015
50352 .-003,032,000,202,096,133,130
50358 :098, 074, 005, 098, 073, 255, 017
50364 : 049, 253, 166, 097, 202, 133, 064
50370 : 097 , 173 , 051 , 002 , 074 , 042 , 121
50376 :202, 208, 252, 005, 097, 145, 085
50382 : 253 , 096 , 141 , 050 , 002 , 174, 154
50388 :236, 196, 221, 236, 196, 240 ,001
50394 : 004, 202, 208, 248, 096, 202, 154
50400 : 138, 010, 170, 189, 021, 197, 181
50406 :072, 189,020, 197,072,096,108
50412 :039, 133, 137, 134, 138, 077, 126
50418 : 074 , 147 , 018 , 145 , 017 , 1 57 , 032
50424 : 029, 135, 139, 049, 050, 051, 189
50430 : 052, 019, 136, 140, 033, 034, 156
50436 :035, 036, 086, 083, 076, 024, 088
50442 : 088 , 089 , 066 , 032 , 160 , 043 , 232
50448 :045, 004, 095, 070, 010, 193, 177
50454 : 234 , 192 , 088 , 193 , 042 , 193 , 196
50460 : 134, 193, 193, 193, 051, 194, 218
50466 : 217, 192, 097, 197, 107, 197, 017
50472 : 113, 197, 127, 197, 161, 197, 008
50478 : 214, 197, 232, 197, 232, 197, 035
50484 : 232, 197, 232, 197, 249, 197, 076
50490 :004, 198,032,198,064, 198,240
50496 : 064 , 198 , 064 , 198 , 064 , 198 , 082
50502 : 144, 198, 254, 199, 165, 200, 206
50508 : 188, 200, 143, 197, 152, 197, 129
50514 : 103, 197, 088, 196, 088, 196, 182
50520 : 202, 198, 216, 198, 035, 201, 114
50526 : 051 , 202 , 060 , 202 , 206 , 045 , 092
50532 :002, 076, 139, 197, 238, 033, 017
50538 : 208 , 096 , 2 38 , 045 , 002 , 076 , 003
50544 : 139, 197, 206, 044, 002, 173, 105
50550 : 048, 002, 240, 017, 206, 044, 163
50556 :002, 076, 139, 197, 238, 044, 052
50562 :002, 173,048,002,240,003,086
50568 :238, 044, 002, 104, 104, 076, 192
50574 : 224, 195, 173, 029, 208, 073, 020
50580 : 001, 141, 029, 208, 096, 173, 028
50586 : 023, 208, 073, 001, 141, 023, 111
50592 : 208 , 096 , 169 , 016 , 141 , 048 , 070
50598 : 002 , 169 , 001 , 141 , 028 , 208 , 203
144
High-Speed Graphics: 3
50604 : 032 , 007 , 192 , 162 , 001 , 142 ,196
50610 :051, 002, 189,003,192,141,244
50616 :032, 208, 173, 004, 192, 141, 166
50622 : 037, 208, 173, 005, 192, 141, 178
50628 :039 , 208 , 173 , 006 , 192 , 141 , 187
50634 : 038 , 208, 173 , 044, 002 , 041 , 196
50640 : 254 , 141 , 044 , 002 , 076 , 1 39 , 096
50646 : 197 , 169, 000 , 141 , 048, 002 , 003
50652 : 141 , 032 , 208 , 141 , 028 , 208 , 210
50658 : 173, 004, 192, 141, 039, 208, 215
50664 :096, 056, 173, 050, 002, 233, 074
50670 :049, 141,051,002, 170, 189,072
50676 :003, 192, 141, 032, 208, 096, 148
50682 : 169 , 000 , 141 , 044 , 002 , 141 , 235
50688 :045, 002, 076, 139, 197, 032, 235
50694 :218, 192,032,007,192,032, 167
50700 : 218, 192,032,007,192,032, 173
50706 : 184, 192, 160, 000, 177, 253, 216
50712 : 153, 109, 202,200,192,064,176
507 18 : 208 , 246 , 096 , 032 , 184 , 192 , 220
50724 : 160, 000, 185, 109, 202, 145, 069
50730 : 253 , 200 , 192 , 064, 208 , 246 , 181
50736 :096 , 144, 005 ,028 , 159 , 156 , 124
50742 :030, 031, 158, 129, 149, 150, 189
50748 :151, 152, 153, 154, 155, 169, 226
50754 : 161, 160, 194, 032, 181, 194, 220
50760 :032 , 103 , 202 , 162 , 000 , 221 , 024
50766 : 049, 198 ,240, 008, 232, 224, 005
50772 :016, 208, 246, 076, 177, 194, 233
50778 : 056, 173,050,002,233,033,125
50784 : 168, 138, 153, 003, 192, 173, 155
50790 : 048, 002, 208, 009, 173, 004, 034
50796 :192, 141, 039, 208, 076, 133, 129
50802 :198, 173,004,192,141,037,091
50808 :208, 173, 005, 192, 141, 039, 110
50814 : 208, 173,006, 192,141,038,116
50820 : 208,174,051,002,189,003,247
50826 : 192 , 141 , 032 , 208, 076 , 177 , 196
50832 : 194, 169, 180, 160, 198, 032, 053
50838 : 181, 194, 032, 228, 255, 056, 072
50844 : 233, 048, 048, 248, 201, 010, 176
50850 : 176, 244, 133,097,056, 169,013
50856 :009, 229,097,010,010,010,021
50862 : 141 , 053 , 002 , 076 , 177 , 194 , 049
50868 :067 , 085 , 082 , 083 , 079 , 082 , 146
50874 : 032 , 086 , 069 , 076 , 079 , 067 , 083
50880 : 073, 084, 089, 032, 040, 048, 046
50886 : 045, 057, 041, 063, 095, 173, 160
50892 :043, 002, 201, 255, 240, 006, 183
3: High-Speed Graphics
50898 : 238, 043 , 002 , 032 , 059 , 196 , 012
50904 : 096 , 206 , 043 , 002 , 032 , 184 , 011
50910 : 192 , 165 , 046 , 197 , 254 , 144 , 196
50916 :004, 238 ,043 , 002 , 096 , 032 , 131
50922 : 059 , 196 , 096 , 160 , 000 , 140 , 1 17
50928 :055, 002, 169, 164, 032, 210, 104
50934 : 255, 169, 157, 032, 210, 255, 044
50940 :032 , 103 , 202 , 172 , 055 , 002 , 050
50946 : 133, 097, 169, 032, 032, 210, 163
50952 :255, 169, 157, 032, 210, 255, 062
50958 : 165 , 097 , 201 , 013 , 240 , 043 , 005
50964 : 201 , 020 , 208 ,013,192, 000 , 142
50970 : 240, 211, 136, 169, 157, 032, 203
50976 :210, 255, 076, 239, 198, 041, 027
50982 : 127 , 201 , 032 , 144, 196 , 192 , 162
50988 :020, 240, 192, 165, 097, 153, 143
50994 : 000, 002 , 032 , 210 , 255 , 169 , 206
51000 : 000, 133, 212, 200, 076, 239, 148
51006 : 198 , 169 , 095 , 153 , 000 , 002 , 167
51012 :152, 096, 032, 231, 255, 169, 235
51018 : 133, 160, 194, 032, 181, 194, 200
51024 :032, 103, 202, 162, 001, 201, 013
51030 :084, 240,011 , 162 ,008, 201 , 024
51036 :068, 240, 005, 104, 104, 076, 177
51042 : 177, 194, 141, 054, 002, 160, 058
51048 :000, 169, 001, 032, 186, 255, 235
51054 : 169, 151, 160, 194,032,237,029
51060 :194, 032, 237, 198, 208, 007, 224
51066 : 173, 054, 002, 201, 084, 208, 076
51072 : 237, 173, 054, 002, 201, 068, 095
51078 : 208 , 066 , 169 , 064 , 141 , 020 , 034
51084 :002, 169, 048, 141, 021, 002, 011
51090 : 169 , 058 , 141 , 022 , 002 , 160 , 186
51096 :000 , 185 , 000 , 002 , 153 , 023 , 003
51102 : 002, 200, 204, 055, 002, 208, 061
51108 :244, 169, 044, 153, 023, 002, 031
51114 : 169, 080, 153, 024, 002, 173, 003
51120 :050, 002, 201, 083, 208, 012, 220
51126 : 169, 044, 153, 025, 002, 169, 232
51132 :087 , 153 ,026 ,002 , 200, 200 ,088
511 38 : 200 , 200 , 200 , 200 , 200 , 076 , 246
51144 :216, 199, 160, 000, 185, 000, 192
51150 :002, 153, 020, 002, 200, 204, 019
51156 :055, 002, 208, 244, 152, 162, 011
51162 :020, 160, 002, 032, 189, 255, 108
51168 :169, 160, 133, 178, 096, 083, 019
51 174 : 065 , 086 , 069 , 032 , 065 , 076 ,111
51180 : 076, 032, 070, 082, 079, 077, 140
51186 : 032 , 072 , 069 , 082 , 069 , 063 , 1 17
146
High-Speed Graphics: 3
51192 : 032, 040, 089, 047 ,078, 041, 063
51198 : 095, 032, 070, 199,032, 184,098
51204 : 192, 169, 229, 160, 199, 032, 217
51210 s 181, 194, 032, 103, 202, 201, 155
51216 :089 , 208 , 007 , 162 ,000 , 160, 130
51222 :064, 076, 037, 200, 024, 165, 076
51228 :253, 105, 064, 170, 165, 254, 015
51234 : 105, 000, 168, 165, 253, 133, 090
51240 : 251, 165, 254, 133, 252, 032, 103
51246 : 195, 200, 169, 251, 032, 216, 085
51252 : 255, 176, 011, 032, 183, 255, 196
51258 : 208, 006, 032, 205, 200, 076, 017
51264 :177, 194, 032, 205, 200, 032, 136
51270 : 231, 255, 173, 054, 002, 201, 218
51276 : 068, 240, 013, 169, 114, 160, 072
51282 : 194, 032, 181,194,032,103,050
51288 :202, 076, 177, 194, 169, 000, 138
51294 :032, 189, 255, 169,015, 162, 148
51300 : 008, 160,015,032,186,255,244
51306 :032, 192, 255, 162,015,032,026
51312 : 198, 255, 160, 000, 032, 207, 196
51318 : 255, 201, 013, 240, 007, 153, 219
51324 : 000 , 002 , 200 , 076 , 116 , 200 , 206
51330 : 169, 095, 153,000,002,032,069
51336 :204, 255, 169, 000, 160, 002, 158
51342 : 032, 181, 194, 162, 015, 032, 246
51348 : 201, 255, 169, 073, 032, 210, 064
51354 : 255, 169, 013, 032, 210, 255, 064
51360 :032, 231, 255, 076, 086, 200, 016
51366 : 032, 070, 199,032,195,200,126
51372 :032, 184, 192, 169, 000, 166, 147
51378 : 253, 164, 254, 032, 213, 255, 069
51384 : 176, 136, 076, 205, 200, 169, 122
51 390 : 004 , 141 , 1 36 , 002 , 000 ,169,130
51396 1000,141,021,208,169,147,114
51402 : 076 , 210, 255 , 169 ,001 , 141 , 030
51408 :021, 208, 169, 147, 032, 210, 227
51414 : 255, 032, 059, 196, 032, 007, 027
51420 :192,076,177,194,248,169,252
51426 : 000 , 141 , 000 , 001 , 141 , 001 , 254
51432 :001, 224, 000, 240, 021, 202, 152
51438 : 024 , 173 , 000 , 001 , 105 , 001 , 030
51444 : 141, 000, 001, 173, 001, 001, 049
51450 : 105 , 000, 141 , 001 , 001 , 076 , 062
51456 :233, 200, 216, 173, 001, 001, 056
51462 : 009 , 048 , 141 , 002 , 001 , 173 ,124
51468 :000 , 001 , 041 , 240 , 074 , 074 , 186
51474 : 074 , 074 , 009 , 048 , 141 , 001 , 109
51480 :001, 173, 000, 001, 041, 015, 255
147
3: High-Speed Graphics
51486 s 009 , 048 , 141 , 000 , 001 , 096 , 069
51492 :056, 165, 045, 233, 002, 133, 158
51498 :045 , 165 , 046 , 233 , 000, 133 , 152
51504 :046 , 169 , 001 , 133 ,097 , 169 , 151
51510 :008, 133, 098, 169, 000, 133, 083
51516 :057, 133, 058, 160, 000, 177, 133
51522 :097, 200, 017, 097, 240, 027, 232
51528 :160, 002, 177, 097, 133, 057, 186
51534 .-200,177,097,133,058,160,135
51540 :000, 177, 097, 072, 200, 177, 039
51546 : 097 , 133 , 098 , 104 , 133 , 097 , 240
51552 :076, 063, 201, 024, 165, 057, 170
51558 : 105, 001, 133, 057, 165,058,109
51564 : 105, 000, 133, 058, 032, 184, 108
51570 : 192 , 160 , 000 , 1 32 , 098 , 160, 088
51576 :000, 024, 165, 045, 105, 037, 240
51582 : 145 , 045 , 200 , 165 , 046 , 105 , 064
51588 :000,145;045,200,165,057,232
51594 : 145, 045, 200, 165, 058, 145, 128
51600 : 045, 200, 169, 131, 145, 045, 111
51606 : 200, 132, 097, 164, 098, 132, 205
51612 :098, 177, 253, 170, 032, 224, 086
5 1618 : 200 , 164, 097 , 173 , 002 , 001 , 031
51624 : 145, 045, 173, 001, 001, 200, 221
51630 : 145, 045, 173,000,001,200,226
51636 :145, 045, 200, 169, 044, 145, 160
51642 :045, 200, 132, 097, 164, 098, 154
51648 :200, 152, 041, 007, 208, 213, 245
51654 : 132,098, 164,097, 136, 169, 226
51660 :000, 145, 045, 160, 000, 177, 219
51666 : 045 , 072 , 200 , 177 , 045 ,133,114
51672 :046, 104, 133, 045, 230, 057, 063
5 1678 : 208 , 002 , 230 , 058 , 164 , 098 , 214
51684 : 192, 064, 208, 143, 160, 000, 227
51690 : 152 , 145 , 045 , 200 , 145 , 045 , 198
51696 :024 , 165 ,045 , 105 , 002 , 133 , 202
51702 :045 , 165 , 046 , 105 , 000 , 133 , 228
51708 :046, 076, 094, 166, 032, 135, 033
51714 : 193, 173, 045, 002, 010, 109, 022
51720 : 045 ,002 , 168 , 162 , 000 , 185 , 058
51726 : 173, 202, 157, 237, 202, 200, 161
51732 :232, 224, 003, 208, 244, 032, 195
51738 : 135, 193, 173,045,002,010,072
51744 : 109, 045, 002, 168, 162, 000, 006
51750 : 177, 253, 029, 237, 202, 145, 057
51756 : 253 , 200 , 232 , 224 , 003 , 208 , 140
51762 : 243, 096, 173,056,002,073,181
51768 :001 , 141 , 056 , 002 , 096 , 032 , 128
51774 : 184, 192, 160,000, 162,060,052
148
High-Speed Graphics: 3
51780 :169, 003, 133, 097, 177, 253, 132
51786 : 157, 173, 202, 200, 232, 198, 212
51792 :097 , 165 , 097 , 208 , 243 , 138 , 004
51798 :056, 233, 006, 170, 016, 232, 031
51804 : 160 , 062 , 185 , 173 , 202 , 145 , 251
51810 : 253, 136,016,248,096,032, 111
51816 :228, 255, 240, 251, 096, 013, 163
149
Chris Metcalf
The Graphics
Package
Creating graphics with machine Working in the Commo-
language routines is one of the dore's high-resolution mode
most effective ways to use ML. can be rewarding, but it can
Machine language is fast, just also be frustrating. If you're
the thing for displaying complex programming exclusively
patterns on the screen, especially in BASIC > plotting points,
when you're using the high- ^°%^a, fflUng in areas,
resolution mode on the 64. These or even domgsmiple things
£ , x . , . , such as clearing the screen
four short routines, combined and sd ecting graphics
or used singly, make graphics modes can be hard work
creation quick and simple. worst of all, the graphics
are drawn on the screen with excruciating slowness.
Fortunately, machine language routines can overcome this lack
of speed. Each of the four programs in "The Graphics Package" can
create dazzling displays at machine language speed with a single SYS
command. And because they're listed in a BASIC loader form, you
won't have any trouble adding them to your own programs.
Using these four routines, you'll be able to plot a point on the
screen, draw a line, fill an area, set graphics or text mode, clear the
screen, or set the high-resolution display color. The point-plotting
routine is the only one that can operate alone; the others are inde-
pendent of each other, but each requires that the plot routine be
present in memory. To call one of the routines, you don't need to
POKE values into memory locations. Instead, you simply call the
routine with a SYS command and follow it with the appropriate
parameters. For example:
SYS(49152),147,83,1
turns on (plots) the pixel at x-position 147 and y-position 83. The
parameters for the other routines are set in the same way. Each rou-
tine explains its parameters and values allowed.
In or Out
All of these SYS commands can be used in direct mode (without line
numbers) or called from within your own program, as long as the
routines have been loaded into your 64 's memory. In a program, treat
them as normal BASIC commands. In other words, use a colon to
150
High-Speed Graphics: 3
separate the different commands. For instance,
FOR I = TO 319:SYS(49152),I,I/319* 199,1,2:NEXT I
draws a line from the upper left-hand corner of the screen to the lower
right-hand corner. Although this is an example of the plot routine,
you end up with a line because of the way you're turning high-
resolution pixels on. Notice, too, the complexity of the second
numeric expression in the above example. In fact, any expression
that creates a number can be used in place of an integer.
One warning when you use these routines: Make sure you don't
press the RUN/STOP-RESTORE keys while they are actually process-
ing. Since the routines that normally control the computer are absent
while these graphics utilities run, attempting to return control to
them can be disastrous. Since the plot and line-drawing routines
operate quickly, and since the fill routine includes a check for the
STOP key, this has been minimized as much as possible. To halt a
fill, just press the STOP key.
Applications, Not Tutorials
Since this package of utilities is meant to use, and not actually to show
you how to create high-resolution graphics from scratch, it's best to
go elsewhere if you're not familiar with programming graphics in
high-resolution mode. Two excellent references are COMPUTE! "s
Reference Guide to Commodore 64 Graphics, by John Heilborn, and
COMPUTE! "s First Book of Commodore 64 Sound and Graphics,
which includes a number of articles showing you the basics of high-
resolution graphics programming. Of course, if you're already
comfortable with this feature of the Commodore 64, you can use
these routines immediately. And even if you aren't an expert in
high-resolution graphics, you can type in the routines and the demon-
stration program, just to see how it all works. After examining the
demonstration, you can easily change some of the parameters to see
new designs.
Type In and Use
To use these routines, all you need to do is type them in. Make sure
you read Appendix C, "The Automatic Proofreader," before you do
this. It will insure mistake-proof entry. Each of the routines also
includes a final checksum of the DATA statements entered. This
checksum will tell you if you have the numbers entered correctly.
Before you run any of these routines for the first time, SAVE them
to tape or disk. A single error can cause the computer to crash, forcing
you to turn it off, then on again, to regain control. Of course, this
151
3: High-Speed Graphics
will erase all of your work unless it was previously saved.
You can add these routines to your own programs easily, just by
altering the first three line numbers to fit into your program. Once
the data has been POKEd into the appropriate memory locations, you
can access the routine. If you want, you can use this graphics package
by itself, and even see a demonstration of its capabilities. Load and
RUN each of the routines, one at a time; then type in and RUN
Program 5, "Package Demonstration," to see the routines operate.
Most of the time, you'll be using all these routines together. To
make it easier to enter the high-resolution (bitmapping) mode, use
Program 4, "Utilities," whenever you use any of the first three rou-
tines. Program 1, "Point Plotting," is the only routine which can
stand on its own. The others — Program 2, "Line Drawing," and
Program 3, "Area Fill" — need to have the point-plotting routine in
memory in order to work.
Each of the routines in Graphics Package is explained in more
detail below.
The Point-Plot Routine
The first, and most crucial, routine is responsible for plotting
individual points. Once this routine has been loaded, you can plot
a point on the screen by SYSing location 49152, and specifying
parameters in the form:
SYS(49152)*y>,m
The first number after the SYS location is the x-position of the point
to be plotted, and the second number is the y-position. On the
Commodore 64, the high-resolution (bitmap) screen is 320 pixels
(picture elements, or dots on the screen) wide and 200 pixels high.
The location 0,0 corresponds to the upper left-hand corner, and
319,199 specifies the lower right-hand corner. Anything outside this
range will return an PILLEGAL QUANTITY ERROR message.
The third number (designated m above) sets the mode of the
plotting routine. There are three possibilities for this setting:
Erase the pixel at the x,y coordinate given.
1 Turn on the pixel (plot the point).
2 Do an exclusive OR on the point. This term, which comes from logic and
machine language programming, means that we blank the point if it's
on, and plot it if it's not. That way, if we plot the point twice with
mode 2, it will return to its original state.
A fourth number can be specified: an optional color. The
number can be from to 15 , corresponding to the Commodore 64 's
152
High-Speed Graphics: 3
color numbers. If specified, the routine will plot the point in the given
color. Otherwise, the point will appear in the pixel color already
assigned to that area (see the COIDR command in Program 4,
"Utilities," for a way of setting the pixel colors on the entire screen).
A few examples of point plotting:
SYS(49152),12,13,1,1 plots apoint in white at coordinate 12, 13.
SYS(49152),319,199,0 erases the point at 319,199 (no color).
SYS(49152),160,100,2,11 reverses (exclusive OR) the point at
160,100 and plots dark gray (color 11).
SYS(49152),0,0,1 plots apoint in the local color at 0,0.
Remember that to use this point-plotting routine, you must be
in the high-resolution mode. If you remain in the normal (text) mode,
these commands will do nothing. The easiest way to enter the high-
resolution mode is to have placed Program 4, Utilities, in memory.
Then you can set the screen for high-resolution graphics with a single
SYS. Read the explanation of the //command in the Utilities
description.
There is one difficulty with the use of color in the pure high-
resolution mode that I've been describing. The colors (foreground
or pixels, and background) are defined not for each pixel, but for each
group of 8 x 8 pixels (equivalent to one character in normal text
mode). Therefore, plotting two pixels close together in different
colors cannot be done, unless they are in different 8x8 blocks.
Multicolor Plotting. There is a solution to this problem. A
special multicolor mode exists on the Commodore 64 which allows
up to four different colors, including the background, to occupy one
8x8 area. Unfortunately, only 160 separate dots can be plotted
horizontally, not 320. This decreases resolution. When in multicolor
mode, therefore, another number has to be included, to specify
which of the three foreground colors you wish to use. This parameter,
which I call the brush, follows the mode number when in multicolor.
(Enter the multicolor mode by typing SYS(50400),m when Program
4, Utilities, is in memory.) The brush is required, as is the mode, and
uses a value from 1 to 3. Following the brush number is the color, if
you wish to specify it. Otherwise, it will plot a pixel with the specified
brush but in the previously defined color in that 8x8 square. Here
are a few more examples of multicolor plotting:
SYS(49152),0,0,1,1,3 will plot a pixel in brush 1 in the color cyan
at coordinate 0,0.
SYS(49152),160,100,2,3,7 reverses the pixel at 160,100 (the
center of the screen) with brush 3 and sets the color to yellow).
SYS(49152),319,0,0 erases the pixel at the top right.
153
3: High-Speed Graphics
U
M
(Note that in multicolor mode an erase command can take only three — '
parameters: x-position, y-position, and the zero indicating erase.
Brush and color cannot apply, so they must be left out.) } |
The decrease in resolution has an effect on the plotting of multi- — 1
color points. The full range of 0-319 is still legitimate, but since
there are in fact only 160 points horizontally, even-numbered x- M
positions will generate the same point as the next higher x-position . 1 — 1
For example SYS(49152),136,43,1,2 andSYS(49152),137,43,l,2 plot
the same point.
The Line-Draw Routine
This routine is a logical extension of the point-plotting routine and
obeys all the rules specified above. However, two points must be
specified after the SYS, so that the line can have a starting and ending
point. The location of the routine is 49600, so a SYS(49600) followed
by two pairs of x,y coordinates, the mode, the brush (if in multi-
color), and the color, if desired, will draw a line anywhere on the
screen. As with the point-plotting routine, the line-drawing routine
will draw lines both in normal high-resolution mode and in multi-
color mode. Here are a few examples to show you the format:
SYS(49600),0,0,319,199,1 draws aline from corner to corner, in
whatever colors lie beneath the pixels in each square.
SYS(49600),160,100,160 + COS(I)* 100,100 + SIN(I)* 100,1,4
draws a line from the center of the screen to a point on a
circle with a radius of 100 at I radians, in the color purple.
SYS(49600),0,0,319,0,2,1 plots a white line across the top of
the screen. Execute this command again and the line disappears.
In multicolor:
SYS(49600),0,0,319,199,1,2,3 draws a line corner to corner in
brush 2, color cyan (3).
SYS(49600),33,75,108,9,2,3 exclusive ORs the line with brush
3, but does not change the color. i >
Note that the easiest way to enter either normal high-resolution
mode or multicolor mode is to use the commands available in
Program 4, Utilities. Lj
The Area-Fill Routine
This routine will fill an area within a certain border with the specified ) f
pixel type and, if designated, a particular color. The fill routine obeys ~~ J
the rules outlined in the point-plotting description. The fill routine
U
154
High-Speed Graphics: 3
begins at 50000, so a SYS(50000),ay>, mode,brush,color call begins a
fill starting at coordinates x,y. The routine can fill any area that is not
too complicated (and too complicated is a very high ceiling for this
routine); typically a border of some sort is set up first, then the routine
is called to fill it in. The fill routine is designed to slip through any
hole between two horizontal or two vertical pixels; diagonally sepa-
rated pixels (for instance, 45,89 and 44,90) act as an effective border.
The edge of the screen also acts as a border if no pixel border is
specified, or if the fill routine slips between two pixels. The routine
can be called with mode set either to fill an empty area with pixels
(mode 1) or to erase an area already covered with pixels (mode 0).
Mode 2 is not allowed: It's a little vague what might constitute a
border for such a fill. Two straightforward examples:
SYS(50000),160,100,1,6 fills starting at coordinates 160,100,
coloring blue as the fill progresses.
SYS(50000),0,0,0 erases an area starting at the top-left corner
of the screen.
Multicolor works as it does with plot and line, but the concept of
a border can be changed with three separate types of plotting. Nor-
mally, this routine takes pixels of the mode it was called with as
boundary pixels (off pixels with mode 0, on pixels with mode 1,
for example, in normal high resolution). In multicolor the routine
assumes that a boundary can only be of the same brush type that
was specified in the SYS call. Any intervening pixels are simply
covered over. However, it is possible to override the program's assump-
tion about the border pixels. If the first punctuation following the
SYS call is a semicolon rather than a comma, the routine stops at any
pixel that is on, rather than stopping only at those of its own brush
type. A good example of the two types of fill can be found in the last
example in the accompanying program, "Package Demonstration."
In multicolor, SYS(50000), 160,100,1,2 will fill any area enclosed by
brush-2 pixels, disregarding what's inside. By contrast, SYS(50000);
160,100,1,2 will fill an area enclosed by any on pixels, regardless of
the type, and not overwrite anything. The uses of these two options
can be seen in Program 5.
As with the other routines, enter high-resolution mode, or multi-
color mode, by using the SYS(50400),H or SYS(50400),M commands
once Program 4 has been placed in memory.
155
3: High-Speed Graphics
The Utility Routines
The last module, beginning at location 50400, contains a variety
of short but useful routines. To access one, call the routine using
SYS(50400), followed by a comma and the first letter of the com-
mand, and then any necessary parameters. The commands, the
parameters, and their descriptions follow:
High-Resolution Mode. SYS(50400),H sets the screen for high-
resolution graphics. Note, however, that this operation does not
clear the high-resolution screen, nor does it set the colors on the
screen. See WIPE and COLOR, below, for those.
Multicolor Mode. SYS(50400),M sets the screen for multicolor
graphics. Like the above command, however, that's all it does.
Text Mode. SYS(50400),T returns the screen to normal text
mode. Notice, however, that multicolor plotting with brush 3 will
actually change the character colors on the text screen.
Wipe. SYS(50400),W removes all the pixels from the screen.
In normal high resolution this does not mean that the screen will
necessarily be blank. The background colors are individually change-
able in each square; at power-up, they can be anything. Use the
COLOR command to restore the background colors to what you want.
Color. There are two distinct modes for this command, one for
normal high resolution and one for multicolor. For high resolution,
the command syntax is SYS{50400),C,border,background,pixel color.
The border color corresponds to location 53280; the background
sets location 53281 and, square by square, the bitmap color area. The
pixel color is the color that any command without color specified
will plot in. So if you enter SYS(50400),C,0,0,5, any commands which
don't specify color will show up in green on black. The second
syntax of this command, for multicolor, is SYS(504QO),C,border,
background,coll,col2,col3. Border and background (53280 and
53281) are as above; coll, col2, andcol3 establish the defaults for the
three brushes, brush 1, brush 2, and brush 3. However, brush-3
colors are sensitive to any PRINT statements, since PRINT puts color
information in the area used for brush 3's color. Scrolling or clearing
the screen also alters or destroys brush-3 color information. The
COLOR command does not just set up default colors passively; it
can also be used to alter the colors of things already plotted, both in
multicolor and standard modes. See the examples of COLOR in the
demonstration program.
156
High-Speed Graphics: 3
Showing Off
To see the complete Graphics Package in action, first load and run all
four routines. Now they're in the computer's memory. Type NEW,
then load Program 5 • Enter RUN and watch it all work. Pressing any
key moves to the next screen display. And since the demonstration
program is all in BASIC, you won't find it hard to change the SYS
commands' parameters and alter the graphics.
Program 1. Point Plotting
For mistake-proof program entry, be sure to read ' 'The Automatic Proofreader, "Appendix C.
10 FOR
XT
20 IF
30 END
49152
49158
49164
49170
49176
49182
49188
49194
49200
49206
49212
49218
49224
49230
49236
49242
49248
49254
49260
49266
49272
49278
49284
49290
49296
49302
49308
49314
49320
49326
49332
49338
49344
49350
X=49152 TO 49601: READ A: POKE X,A:CIC
CK<>53595 THEN PRINT "ERROR IN DATA"
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
DATA
032,020,
120,169,
132,192,
088,096,
008,192,
064,176,
252,032,
224,200,
132,254,
055, 164,
173,022,
005,032,
224,000,
240,015,
041,003,
010,010,
121,000,
110, 192,
002,096,
158, 173,
162,248,
183,166,
032,246,
023,201,
003,061,
193,076,
093,027,
177,003,
003,036,
165,253,
165,252,
074,074,
133,003,
000,133,
192,032
053,133
169,055
032,110
002,176
018,134
110,192
176,005
096,162
169,255
208,041
110,192
240,019
032,110
208,002
010,133
208,001
138,041
032,115
165,013
154,096
020,164
192,165
002,240
059,193
167,192
193,076
061,059
002,016
074,074
074,165
024,121
185,116
004,160
,056,192
,001,032
,133,001
,192,240
,022,224
,251,132
,208,009
,134,253
,014,076
,133,002
,016,133
,134,006
,165,005
,192,138
,169,003
,005,032
,096,032
,015,133
,000,032
,240,004
,032,247
,021,096
,006,240
,011,177
,029,027
,177,003
,167,192
,193,145
,001,096
,074,168
,251,106
,091,193
,193,105
,000,165
=CK+A:NE
;rem 198
: rem 63
: rem 58
:rem 138
jrem 137
trem 146
: rem 147
:rem 145
srem 149
:rem 147
:rem 144
;rem 144
: rem 149
:rem 132
:rem 132
:rem 132
:rem 131
trem 133
: rem 111
:rem 132
:rem 138
: rem 125
srem 148
:rem 160
srem 156
srem 150
srem 127
:rem 157
srem 158
srem 167
srem 153
srem 125
srem 164
srem 150
srem 152
srem 145
srem 121
157
3: High-Speed Graphics
49356
DATA
005,201,
016,240,017,176
: rem
140
49362
DATA
024, 165,
002,010,010,010
: rem
117
49368
DATA
010,081,
003,041,240,081
: rem
133
49374
DATA
003,145,
003,096,177,003
: rem
146
49380
DATA
041 , 240 , 005 , 002 , 145 , 003
: rem
125
49386
DATA
096,165,
004,009,016,133
: rem
154
49392
DATA
004,165,
002,145,003,096
: rem
143
49398
DATA
165,253,
074,074,074, 170
: rem
166
49404
DATA
165,251,
069,253,041,248
: rem
155
49410
DATA
069,253,
024,125,141,193
: rem
146
49416
DATA
133,003,
189,166,193,101
: rem
150
49422
DATA
252,133,
004,165,251,041
: rem
136
49428
DATA
007,005,
005,170,160,000
: rem
129
49434
DATA
096,128,
064,032,016,008
: rem
150
49440
DATA
004,002,001,064,064,016
: rem
125
49446
DATA
016,004,
004,001,001,128
: rem
125
49452
DATA
128,032,032,008,008,002
: rem
133
49458
DATA
002,192,
192,048,048,012
: rem
153
49464
DATA
012,003,
003,127,191,223
: rem
134
49470
DATA
239,247,
251,253,254,063
: rem
159
49476
DATA
063,207,
207,243,243,252
: rem
154
49482
DATA
252,063,
063,207,207,243
: rem
151
49488
DATA
243,252,
252,063,063,207
: rem
157
49494
DATA
207,243,243,252,252,000
: rem
145
49500
DATA
040,080,
120,160,200,240
: rem
118
49506
DATA
024,064,
104,144,184,224
: rem
145
49512
DATA
008,048,
088,128,168,208
: rem
163
49518
DATA
248,032,
072,112,152,192
: rem
149
49524
DATA
200,200,
200,200,200,200
: rem
106
49530
DATA
200,201,
201,201,201,201
: rem
108
49536
DATA
201,202,
202,202,202,202
: rem
120
49542
DATA
202,202,
203,203,203,203
: rem
122
49548
DATA
203,000,064,128,192,000
:rem
138
49554
DATA
064,128,
192,000,064,128
: rem
151
49560
DATA
192,000,
064,128,192,000
: rem
139
49566
DATA
064,128,192,000,064,128
: rem
154
49572
DATA
192,000,
224,225,226,227
:rem
147
49578
DATA
229, 230,
231,232,234,235
: rem
153
49584
DATA
236,237,
239,240,241,242
: rem
158
49590
DATA
244,245,
246,247,249,250
: rem
165
49596
DATA
251,252,
254,013,013,013
: rem
143
Program 2. Line Drawing
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
10 FOR X=49600 TO 49911 :READ A: POKE X,A:CK=CK+A:NE
XT :rem 200
20 IF CKO40651 THEN PRINT "ERROR IN DATA" :rem 52
30 END :rem 58
158
High-Speed Graphics: 3
49600
DATA
032
020,192
160,
003,
185
: rem
132
49606
DATA
251
,000,153
193
000
,136
: rem
135
49612
DATA
016
,247,032
,020
,192
,160
: rem
138
49618
DATA
003
,185,251
000
153
168
: rem
147
49624
DATA
000
,136,016
247
032
056
: rem
141
49630
DATA
192
,120,169
053
133
001
: rem
139
49636
DATA
160
,015,185
097
000
153
: rem
150
49642
DATA
248
,194,136
016
247,
162
: rem
162
49648
DATA
002
,181,168
056
245
,193
: rem
163
49654
DATA
149
,038,181
169,
245,
194
: rem
174
49660
DATA
149
,039,169
001
149
108
: rem
161
49666
DATA
169
000,149
109
181
194
: rem
165
49672
DATA
213
,169,144
027
208
006
: rem
154
49678
DATA
181
168,213
193,
176
019
: rem
172
49684
DATA
169
255,149
108,
149
109
: rem
176
49690
DATA
181,
193,056,
245,
168,
149
: rem
172
49696
DATA
038
181,194
245,
169,
149
: rem
180
49702
DATA
039,
202,202,
016,
198,
169
: rem
153
49708
DATA
000
133,104
133,
106,
133
: rem
131
49714
DATA
105
133,107,
166,
038,
164
: rem
151
49720
DATA
039
208,014
228,
040,
176
: rem
149
49726
DATA
010
166,040
032,
081,
194
: rem
144
49732
DATA
133,
104,076
090,
194,
032
: rem
148
49738
DATA
081,
194,133,
106,
076,
090
: rem
160
49744
DATA
194
132,099,
152,
074,
134
: rem
163
49750
DATA
098,
138,106,
096,
169,
000
: rem
162
49756
DATA
133,
102,133,
103
165,
193
: rem
147
49762
DATA
133,
251,165,
194,
133,
252
: rem
155
49768
DATA
165
195,133,
253,
165,
098
: rem
177
49774
DATA
024
105,001,
133,
100,
165
: rem
134
49780
DATA
099
105,000,
133,
101
165
: rem
143
49786
DATA
005
240,014,
165,
159,
197
: rem
164
49792
DATA
253
208,008,
165,
251
041
: rem
154
49798
DATA
254,
197,158,
240,
003
032
: rem
163
49804
DATA
132
192,165,
251,
041,
254
: rem
149
49810
DATA
133
158,165,
253,
133,
159
: rem
157
49816
DATA
162
002,181,
104,
024
117
: rem
139
49822
DATA
038
149,104,
181,
105,
117
:rem
150
49828
DATA
039
149,105,
197,
099,
240
: rem
174
49834
DATA
004
144,033,
208,
006,
181
: rem
143
49840
DATA
104
,197,098,
144,
025
181
: rem
160
49846
DATA
104
,229,098
149
104
181
: rem
165
49852
DATA
105
,229,099
149
105
181
: rem
165
49858
DATA
251
,024,117
108
149
251
: rem
158
49864
DATA
181
,252,117
109
149
252
: rem
162
49870
DATA
202
,202,016,
200
230
102
: rem
123
49876
DATA
208
,002,230
103
,165
,103
: rem
141
49882
DATA
197
,101,144
006
165
102
: rem
150
49888
DATA
197
,100,176
003
076
121
: rem
159
159
3: High-Speed Graphics
49894 DATA 194,160,015,185,248,194 : rem 173
49900 DATA 153,097,000,136,016,247 : rem 147
49906 DATA 169,055,133,001,088,096 :rem 163
Program 3. Area Fill
For mistake-proof program entry, besuretoread "The Automatic Proofreader," 'Appendix C.
10 FOR X=50000 TO 50353 :READ A: POKE X, A:CK=CK+A:NE
XT
: rem
178
20 IF
CK<>44135 THEN PRINT "ERROR IN
DATA" :rem 53
30 END
:rem 58
5 00
~J XJXJ XJXJ
DATA
169 001 111 165 019 191
• y^TTi
• X XSIU
120
UnlA
000 701 04.4. 740 00? 1 9ft
• X CSlll
lift
X xo
5001 9
DATA
165 019 090 1 99 019 056
• X C1U
195
X Z, -J
5001 ft
DATA
199 1 65 006 901 009 90ft
• r6m
129
50094
J XJXJ £. t
nATA
005 162 014 076 055 164
• r*tiT*n
• X fSlll
134
500^0
DATA
x*r\ 1 A
1 65 059 056 99Q 050 901
1U J / u / uJO / L«7f XJJXJ/ £tXJ X.
• x cm
1 99
500^6
OXJXJ J D
DATA
004 176 00^ 076 05"* 164
WWt f X / V/ f XJXJ O f XJ 1 \J f XJ -J -J / X U*T
• T" o m
• x cut
1 17
50049
DATA
165 059 056 9"^^ 00"* 1 ^7
• X cut
1 99
X £t z*
5004ft
nATA
unln
0^*} 1 6Q 000 1 ^ 0^1 1^^
• x em
197
X £. 1
50054
DATA
9Q 1 90 1 6Q 05^ 1 ^ 001
K>67f l^Uf lU7f WJO / X J J g XJXJ J.
• X
130
50060
J It/ JO wKi
nATA
16Q 007 1^^ 164 1 69 pjpM
• JfQin
139
50066
DATA
133 163 165 006.133.034
• X GUI
1 16
X J \J
50079
■J XJXJ 1 £.
nATA
173.022.208 041 016 240
• X Gill
197
x^ /
5007ft
nATA
0?1 165 951 041 954 1 ^
• X Clll
1 16
500ft4
nATA
951 1 <5ft 1 64 9*30 1 6*3 165
• x"6in
151
500Q0
~J XJXJ Z/XJ
nATA
006 940 007 1 65 005 074
• x"6in
1 11
X -J X
500Q6
3XJXJ Z/ \J
nATA
074 074 1 ^ 0^4 1 6Q 000
/ *♦ f V / ** / 1 J J g XJ 0*-r f X v ™ / XJXJ XJ
s rsni
1 49
501 09
nATA
1 097 1 09ft 165 959
■ r6m
1 19
501 0ft
nATA
90ft 004 165 951 940 09Q
s r6m
115
50114
DATA
165 951 056 9 9Q 16*^ 1 7^
• rsni
142
50120
DATA
251,165,252,233,000,133
: rem
122
50126
DATA
252,032,106,196,208,230
:rem
136
50132
DATA
165,251,024,101,163,133
:rem
126
50138
DATA
251,144,002,230,252,230
: rem
125
50144
DATA
253,032,106,196,240,013
: rem
132
50150
DATA
165,027,208,013,032,151
: rem
128
50156
DATA
196,169,001,133,027,208
: rem
146
50162
DATA
004,169,000,133,027,198
: rem
138
50168
DATA
253,198,253,032,106,196
: rem
156
50174
DATA
240,013,165,028,208,013
: rem
133
50180
DATA
032,151,196,169,001,133
: rem
136
50186
DATA
028,208,004,169,000,133
: rem
137
50192
DATA
028,230,253,032,132,192
: rem
135
50198
DATA
165,251,024,101,163,133
: rem
138
50204
DATA
251,144,002,230,252,165
: rem
126
50210
DATA
252,240,006,165,251,201
: rem
122
50216
DATA
064,176,005,032,106,196
: rem
141
50222
DATA
208,175,164,029,240,018
: rem
141
50228
DATA
169,055,133,001,032,234
: rem
135
160
High-Speed Graphics: 3
DATA
255
,032
,234,255,008
, 169
: rem
146
DATA
053
,133,001,040,208
,006
: rem
117
50246
-I XJ £4 TT \J
DATA
169
,055
1 11 01011 PIRR
,096
: rem
152
■JXJ £t J £*
DATA
165,033
111 PI19 1 Ifi
. 177
: rem
139
can cp
n ata
031
, 133
. 251 . 230. 032
. 177
• rem
134
50964
DATA
031
,133
.252.230.032
.177
• rem
132
50270
DATA
031
,133
, 253,132,029
,201
: rem
125
50276
DATA
200
,176
,201,076,180
,195
: rem
146
50282
DATA
032
,246
,192,189,059
,193
: rem
161
50288
DATA
073
,255
,049,003,072
,138
: rem
152
50294
DATA
041
,007
,170,104,228
,164
: rem
138
50300
DATA
176
,006
,074,232,228
,164
: rem
139
50306
DATA
144
,250
,166,165,240
,005
: rem
136
50312
DATA
197
,034
,076,150,196
,201
: rem
143
50318
DATA
000
,240
,003,162,000
,096
: rem
120
50324
DATA
162
,001
,096,164,029
,165
: rem
143
50330
DATA
033
,133
,032,165,251
,145
: rem
129
50336
DATA
031
,230
,032,165,252
,145
: rem
132
50342
DATA
031
,230
,032,165,253
,145
: rem
130
50348
DATA
031
,230
,029,096,013
,013
: rem
133
Program 4. Utilities
For mistake-proof program entry, be sure to read "The Automatic Proofreader" Appendix C.
10 FOR X=50400 TO 50621 :READ A:POKE X , A : CK=CK+1 : NE
XT
: rem
164
20 IF
CK<>222 THEN PRINT "ERROR IN DATA"
: rem
202
30 END
: rem 58
50400
DATA
032,115,000,240
,029,160
: rem
115
50406
DATA
008,217,007,197
,208,018
: rem
146
50412
DATA
185,016,197,141
,252,196
: rem
151
50418
DATA
185,017,197,141
,253,196
: rem
159
50424
DATA
032,115,000,076
,255,255
: rem
134
50430
DATA
136,136,016,229
,162,011
:rem
133
50436
DATA
076,055,164,072
,044,077
: rem
153
50442
DATA
044,084,044,087
,044,067
: rem
149
50448
DATA
026,197,056,197
,065,197
: rem
172
50454
DATA
089,197,109,197
,173,000
: rem
160
50460
DATA
221,041,252,141
,000,221
: rem
115
50466
DATA
169,040,141,024
,208,173
: rem
144
50472
DATA
017,208,009,032
,141,017
: rem
134
50478
DATA
208,173,022,208
,041,239
: rem
148
50484
DATA
141,022,208,096
,032,026
: rem
139
50490
DATA
197,009,016,141
,022,208
: rem
141
50496
DATA
096,173,000,221
,009,003
: rem
137
50502
DATA
141,000,221,169
,021,141
: rem
118
50508
DATA
024,208,173,017
,208,041
: rem
138
50514
DATA
223,141,017,208
,076,047
: rem
140
50520
DATA
197,169,000,168
,132,003
: rem
139
3: High-Speed Graphics
50526
DATA
162
,224
,134,004,145,003
: rem
130
50532
DATA
200
,208
,251,232,224,000
: rem
120
50538
DATA
208
,244
,096,032,110,192
: rem
145
50544
DATA
142
,032,208,032,110,192
: rem
129
50550
DATA
138
,041
,015,141,033,208
: rem
130
50556
DATA
133
,252
,032,110,192,138
: rem
138
50562
DATA
041
,015
,133,251,173,022
: rem
129
50568
DATA
208
,041
,016,240,019,032
: rem
137
50574
DATA
110
,192
,138,041,015,133
: rem
135
50580
DATA
252
,032
,110,192,169,216
: rem
141
50586
DATA
133
,004
,138,032,172,197
: rem
149
50592
DATA
169
,200
,133,004,165,251
: rem
140
50598
DATA
010,010
,010,010,005,252
: rem
115
50604
DATA
160
,000
,132,003,162,004
: rem
114
50610
DATA
145
,003
,200,208,251,230
: rem
120
50616
DATA
004
,202
,208,246,096,013
: rem
137
Program 5. Package Demonstration
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
100 : :rem 203
110 REM DEMOS FOR GRAPHICS SUBROUTINES : rem 137
120 REM :rem 119
130 : :rem 206
140 SYS50400,H:SYS50400,C,0,0,1:GOSUB700 :rem 8
150 DATA "{WHT}SIMPLE FIGURE NUMBER 1" : rem 127
160 DATA "HIT ANY KEY AFTER THIS DESIGN, AND ALL"
:rem 231
170 DATA "FOLLOWING DESIGNS, ARE COMPLETE" : rem 17
180 DATA "TO GO ON TO THE NEXT ONE.", : rem 204
190 FORI=0TO270STEP5 :SYS49600, I , 100+SIN( l/50)*100,
319-1, 100+COS(I/25)*50,1:NEXT : rem 241
200 GETA$:IFA$=""THEN200 : rem 71
210 GOSUB700 :rem 170
220 DATA "THIS FIGURE IS DRAWN IN HIRES THEN"
: rem 69
230 DATA "REDISPLAYED IN MULTICOLOR FOR AN": rem 64
240 DATA "INTERESTING EFFECT", : rem 25
250 FORI=0TO309STEP2 : SYS49600, I , 100+SIN( l/50)*100,
I+10,100+SIN(I/50)*50,1:NEXT : rem 179
260 GOSUB640:GOSUB700 : rem 3
270 DATA "HIRES/MULTICOLOR FIGURE NUMBER 2",
: rem 148
280 FORI=0TO309STEP2 : SYS49600 , I , 100+COS ( 1/50 ) * 100 ,
1+10, 100+SIN( 1/50)* 50, 1:NEXT : rem 177
290 GOSUB640:GOSUB700 : rem 6
300 DATA "SIMPLE FIGURE NUMBER 2", : rem 164
310 FORI=0TO319STEP2 : SYS49600 , I , 100+SIN( 1/50 ) *100 ,
319-1, 100+COS(I/50)*50,1 :rem 113
162
High-Speed Graphics: 3
320 NEXT :rem 212
330 GETA$:IFA$=""THEN330 : rem 79
340 GOSUB700 :rem 174
350 DATA "SIMPLE FIGURE NUMBER 3" : rem 126
360 DATA "TWO FILLS AT 0,0 AND 319,199 ARE SHOWN"
: rem 50
370 DATA "AFTER YOU HIT ANY KEY; THESE FILLS"
: rem 75
380 DATA "GIVE AN IDEA OF THE FILL MECHANISM",
: rem 36
390 FORI=0TO310STEP5:SYS49600,I,100+SIN(I/50)*100,
319-1, 100+SIN(I/50)*50,2:NEXT : rem 242
400 GETA$ : IFA$=" "THEN400 : rem 75
410 SYS50000,0,0,1:SYS50000, 319, 199,1 :rem 193
420 GETA$ : IFA$=" "THEN420 : rem 79
430 GOSUB700:SYS50400,C,11,15,11 : rem 253
440 DATA "THE NEXT IMAGE IS A CIRCLE WITH THE"
: rem 37
450 DATA "RADII PLOTTED AS ' EXCLUSIVE-OR' " , : rem 16
460 FORI=0TO2*2"i/100STEP T/100 5 SYS49600 , 160 , 100 , 16
0+COS(I)*100,100-SIN(I)*80,2 :rem 94
470 NEXT :rem 218
480 GETA$ : IFA$=" "THEN480 : rem 91
490 SYS50400,C,0,0,1:GOSUB700 : rem 106
500 DATA "THIS IS A MULTICOLOR IMAGE" : rem 117
510 DATA "CREATED WITH LINE AND FILL ROUTINES",
:rem 239
520 SYS50400,M:N=32:FORI=0TO2*tSTEP_T/N : rem 191
530 SYS49600 , 160 , 100 , 160+COS ( lj*80 , 100-SIN( I ) *64 , 1
,1,15:NEXT : rem 224
540 N=16 :FORI=0TO2*_T STEPT/N:X=160+COS ( I ) *100 :Y=100
-SIN(I)*80 ~ :rem 135
550 SYS49600,X,Y, 160+COS (I+t/N)* 100, 100-SIN( I+t/N)
*80,1,2,14:NEXT : rem 224
560 SYS50000 ; 160 , 21 , 1 , 3 , 6 : SYS50000 ; , , 1 , 1 , 11
: rem 75
570 SYS49600,0,0,319,0,1,2,2:SYS49600,319,0,319,19
9,1,2,2 :rem 166
580 SYS49600 , 3 19 , 199 , , 199 , 1 , 2 , 2 : SYS49600 ,0,199,0,
0,1,2,2 :rem 179
590 GETA$:IFA$=""THEN590 s rem 95
600 SYS50000,160,21,1,2,14 : rem 40
610 GETA$:IFA$=""THEN610 s rem 81
620 SYS50400 ,W: PRINT " {CLR} " ; : SYS 50400, T: END
:rera 175
630 : :rem 211
640 GETA$:IFA$=""THEN640 : rem 87
650 SYS50400,M:SYS50400,C,0,0,2,5,1 : rem 129
660 GETA$:IFA$=""THEN660 : rem 91
163
3: High-Speed Graphics
670 SYS50400,H:SYS50400,C, 0,0,1 : rem 191
680 RETURN : rem 126
690 : :rem 217
700 SYS50400 ,W: PRINT " {CLR} {DOWN} " :SYS50400,T:K=0
:rem 101
710 READN$ : IFN$=" "THEN730 : rem 171
720 PRINTTAB ( 20-LEN ( N$ ) / 2 ) N$ " { DOWN } " : K=K+1 : GOTO 710
: rem 27
730 PRINTTAB (17)" §6 @ 3 " : PRINTTAB ( 1 7 ) " { RVS } WAIT
{UP}" :rem 70
740 PORI=1TO350*K:GETA$:IFA$=""THENNEXT :rem 133
750 SYS50400, H: RETURN : rem 34
164
Chapter 4
Game
Programming
□
□
□
□
□
D
□
Gregg Peek
Two-Sprite
Joystick
Machine language joystick One of the greatest advan-
routines are fairly common tages of machine language
game programming aids. You 've is its speed of execution.
probably seen several. This once seemed slow
routine, however, isabitdif- can i nstead seem fast.
ferent, for it allows you to use Ma ,<: hine lan 8 u ^ e is es P e "
two joysticks on the Commodore ^ S Jnd writing rC
64. Not only that, but it lets aJXstykgamIs onyour
you move sprites smoothly and Co mmodore 64 . BASIC is
quickly across the screen. ]mt too slow anc j too cum .
bersome for many of the things you want your game to do. Moving
figures using the joystick is one aspect of game play that suffers
when you have only BASIC to work with. Sprites seem to move even
slower, and when you try to use the right-hand side of the screen,
getting across the invisible "seam" becomes a nightmare of POKEs
and PEEKs. Some programmers use only the left side of the screen
because of this.
"Two-Sprite Joystick" gives you the speed of machine language,
as well as easy use of sprites and joysticks. Once you've included it
as part of your own game program, you'll be able to use both joystick
ports and the entire screen. It moves two sprites, each controlled
by a separate joystick, quickly and smoothly, even across the
dreaded seam.
All the sprite movements are calculated by the routine, including
checking for the seam and keeping the sprites on the screen. You
can use your own sprite data, creating your own sprite design, with
only minor modification. You can even change the color of the
sprites with a single POKE. Writing games, especially two-player
games, becomes much easier when you have this routine in hand.
Smooth and Fast
Type in and save Two-Sprite Joystick. It's in the form of a BASIC loader
which POKEs the machine language routine into an area of memory
safe from any BASIC program. It's a good idea to save the program
before you try to run it. Otherwise, if you've mistyped any part of
the program, and cause the computer to crash, you'd have to turn it
off, then on again, to regain control. That would erase all of your
167
4: Game Programming
typing. Once you have it saved, type LOAD, then RUN. Wait a few
moments for the data to be POKEd into memory, then respond to
the two prompts. Enter a number between and 15 to select the
colors for the two sprites. The blocks then appear on the screen.
Sprite is controlled by the joystick plugged into port 1, while
sprite 1 is controlled by the joystick inserted into port 2 . Maneuver
the sprites around the screen, noticing how quickly and smoothly
each moves, even when it crosses the seam. The sprites stay on the
screen at all times. When you're moving sprite 0, controlled by the
joystick in port 1, you'll see odd characters such as 2, P, or the «-
(back arrow). This is unavoidable in the direct mode of the demon-
stration, but will not occur when you use the routine in your
own program.
To use this routine in your own game, all you have to do is create
two sprites, and POKE the machine language data into memory
with a BASIC loader such as:
10 1=49152
20 READ A: IF A=256 THEN40
30 POKE I,A:I=I+1:CK=CK+A:GOTO20
40 IFCK<>71433THENPRINT"{CLR}ERROR IN DATA STATEME
NTS": END
When you run your complete program (which includes this BASIC
loader and the DATA statements), just SYS 49152 to access the two-
sprite joystick routine. You can even do that from within your
program if you want.
If you want to change the sprites' colors in the middle of the
game, just insert the statement:
POKE 49228,x to change the color of sprite 0, or
POKE 49233,x to change the color of sprite 1, where x in both statements
is the color value, from to 15. The sprite color will
change instantly. For instance, POKEing 49228,14 turns
sprite light blue.
Two-Sprite Joystick
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
40000 FORT=12288T012288+128:POKET,255:NEXT:REM ADD
SPRITE DATA HERE : rem 217
40010 1=49152 :rem 128
40020 READ A: IF A=256 THEN40040 : rem 94
40030 POKE I,A:I=I+1:CK=CK+A:GOTO40020 :rem 169
40040 IFCK <> 7 143 3THENPRINT" {CLRjERROR IN DATA STAT
EMENTS " : END :rem 120
40050 INPUT "COLOR FOR SPRITE0" ; C0 : POKE49228 , C0
:rem 249
168
Game Programming: 4
40060 INPUT "COLOR FOR SPRITE1 " ; CI : POKE49233 , CI
:rem 249
40070 SYS49152 : rem 255
49152 DATA 169,125,141,224,207,169,0 : rem 246
49160 DATA 141,225,207,169,125,141,226 : rem 86
49168 DATA 207,169,0,141,227,207,169 :rem 1
49176 DATA 125,141,0,208,141,1,208 : rem 134
49184 DATA 141,2,208,141,3,208,169 : rem 145
49192 DATA 0,141,16,208,120,169,52 : rem 140
49200 DATA 141,20,3,169,192,141,21 :rem 129
49208 DATA 3,88,96,162,0,32,65 : rem 212
49216 DATA 192,162,1,32,65,192,76 : rem 103
49224 DATA 49,234,169,3,141,21,208 : rem 147
49232 DATA 169,192,141,248,7,169,1 :rem 158
49240 DATA 141,39,208,169,2,141,40 : rem 141
49248 DATA 208,169,193,141,249,7,189 :rem 18
49256 DATA 0,220,41,15,157,228,207 :rem 141
49264 DATA 56,169,15,253,228,207,157 :rem 8
49272 DATA 232,207,160,0,200,152,221 : rem 224
49280 DATA 232,207,208,249,224,1,208 :rem 245
49288 DATA 2,162,2,152,10,168,185 :rem 100
49296 DATA 135,192,72,185,134,192,72 :rem 9
49304 DATA 96,1,194,213,193,217,193 :rem 206
49312 DATA 1,194,225,193,229,193,236 :rem 255
49320 DATA 193,1,194,221,193,250,193 : rem 246
49328 DATA 243,193,1,194,169,50,221 :rem 203
49336 DATA 1,208,176,12,189,1,208 : rem 100
49344 DATA 56,189,1,208,233,1,157 :rem 104
49352 DATA 1,208,96,169,229,221,1 : rem 102
49360 DATA 208,144,12,189,1,208,24 :rem 145
49368 DATA 189,1,208,105,1,157,1 : rem 50
49376 DATA 208,96,56,189,224,207,233 :rem 14
49384 DATA 65,157,228,207,189,225,207 : rem 63
49392 DATA 233,1,29,228,207,144,13 :rem 147
49400 DATA 169,65,157,224,207,169,1 : rem 205
49408 DATA 157,225,207,76,247,192,24 :rem 6
49416 DATA 189,224,207,105,1,157,224 : rem 249
49424 DATA 207,189,225,207,105,0,157 :rem 249
49432 DATA 225,207,56,189,224,207,233 : rem 48
49440 DATA 0,157,228,207,189,225,207 :rem 253
49448 DATA 233,1,29,228,207,144,19 :rem 155
49456 DATA 224,2,240,34,173,16,208 :rem 145
49464 DATA 9,1,141,16,208,189,224 : rem 104
49472 DATA 207,157,0,208,96,224,2 :rem 101
49480 DATA 240,30,173,16,208,41,254 : rem 192
49488 DATA 141,16,208,189,224,207,157 :rem 58
49496 DATA 0,208,96,173,16,208,9 : rem 64
49504 DATA 2,141,16,208,189,224,207 :rem 196
49512 DATA 157,0,208,96,173,16,208 : rem 153
169
4: Game Programming
49520 DATA 41,253,141,16,208,189,224 :rem 246
49528 DATA 207,157,0,208,96,56,189 : rem 170
49536 DATA 224,207,233,25,157,228,207 :rem 47
49544 DATA 189,225,207,233,0,29,228 : rem 207
49552 DATA 207,176,13,169,24,157,224 :rem 1
49560 DATA 207,169,0,157,225,207,76 :rem 207
49568 DATA 127,193,56,189,224,207,233 :rem 63
49576 DATA 1,157,224,207,189,225,207 :rem 4
49584 DATA 233,0,157,225,207,56,189 :rem 212
49592 DATA 224,207,233,0,157,228,207 : rem 250
49600 DATA 189,225,207,233,1,29,228 :rem 201
49608 DATA 207,144,19,224,2,240,34 :rem 144
49616 DATA 173,16,208,9,1,141,16 :rem 47
49624 DATA 208,189,224,207,157,0,208 :rem 255
49632 DATA 96,224,2,240,30,173,16 :rem 94
49640 DATA 208,41,254,141,16,208,189 :rem 252
49648 DATA 224,207,157,0,208,96,173 :rem 211
49656 DATA 16,208,9,2,141,16,208 : rem 51
49664 DATA 189,224,207,157,0,208,96 :rem 216
49672 DATA 173,16,208,41,253,141,16 : rem 198
49680 DATA 208,189,224,207,157,0,208 :rem 1
49688 DATA 96,32,158,192,96,32,178 :rem 183
49696 DATA 192,96,32,198,192,96,32 :rem 182
49704 DATA 78,193,96,32,158,192,32 :rem 169
49712 DATA 78,193,96,32,178,192,32 :rem 170
49720 DATA 78,193,96,32,178,192,32 : rem 169
49728 DATA 198,192,96,32,158,192,32 :rem 225
49736 DATA 198,192,96,96,256 :rem 144
170
Peter Marcotty
Scroll 64
A window can make a static Someone spots a tornado
screen more dynamic. This short and reports it to the local
machine language routine gives weather bureau. Your tele-
you control over screen scrolling vision beeps and a warning
from within BASIC programs. moves across the bottom
of the screen.
How would you create that effect on your 64? How do you make
words scroll sideways?
Scroll Control and Windows
When you LIST a program, the screen fills quickly. As new lines
appear, the screen scrolls from bottom to top (everything moves
up a notch).
But there may be times when you want movement from top to
bottom, or right to left. Or perhaps you want some information to
stay in one section of the screen while everything else moves.
You need a screen window. Things in the window move, while
everything else stays put. Some new computers, such as the Apple
Macintosh, have built-in windowing.
"Scroll 64" won't turn your 64 into a Macintosh, but it can make
your screen displays more dynamic.
Asteroid Belts and Invoices
There are many ways to creatively use screen windows and scrolling.
For example, scrolling is common in certain types of videogames.
You drive a car on a road that moves toward you. Or your spaceship
at the bottom of the screen has to shoot at descending asteroids. In
addition to the action window, there is usually a section with infor-
mation about your current score, remaining fuel, velocity, and so
on. It would be confusing if your score moved with the asteroids, so
the action of the game is put in a window. Your score goes somewhere
outside the window.
Business programs can benefit from windows, as well. You might
want a command line in an invoicing program, to remind the user of
the various options. The window would cover all of the screen
except the last line, which says "Fl = Help F3 = New F5 = Help
F7 = Continue." Everything scrolls on the screen except the line at
the bottom. Another possibility is a product list window in the corner
of the screen. When the user of the invoice program wants to look
up a product number, the window opens up and the list scrolls by.
171
4: Game Programming
Customizing Your Programs
Scroll 64 is a machine language program which goes into memory
locations 49152-49528 ($C000-$C172). It does not use any BASIC
RAM. The BASIC loader program reads the DATA statements and
POKEs the numbers into memory. When the ML program is safe in
memory, type NEW to get rid of the loader and clear RAM.
To use Scroll 64, type LOAD and RUN 60, type NEW, and then
LOAD your own program. To activate it, simply SYS 49152. It scrolls
once and returns to BASIC.
Or if you prefer, you could build the BASIC loader into your pro-
gram. Renumber the lines (starting at 60000, for instance), add a
RETURN, and call it with a GOSUB at the beginning of your program.
Scroll 64 moves a certain section of the screen in a certain direc-
tion, along with the corresponding color memory. These memory
addresses contain the pertinent information:
Location Function
49522 Direction
49523 Left Boundary
49524 Right Boundary
49525 Top Boundary
49526 Bottom Boundary
49527 Horizontal Wrap
49528 Vertical Wrap
Direction is the way in which the screen scrolls. To change it,
POKE 49522 with one, two, three, or four (for left, right, up, or
down respectively). The boundary values define the si2e of the win-
dow. Left and right boundaries can range from to 39. Top and
bottom must be between and 24. When the program is first run, a
five by five window goes in the top-left corner.
The wrap values determine what happens to characters when
they reach the edge of the window. You can make them disappear
or wrap around to the beginning. POKE 49527 and 49528 as follows
Number Effect
Don't wrap around, leave a trail
1 Wrap around
2 Don't wrap around, erase trail
To activate the scroll window, SYS 49152. You can SYS over
and over, changing the direction, boundaries, and wrap values as
you wish. Note that when the ML routine is activated, whatever
is in the window scrolls, but at all other times, the screen acts as it
normally does.
172
Game Programming: 4
Special Loading Instructions
Enter the program and SAVE it before you test anything. To put the
ML into memory, type
RUN 60 (not just RUN)
The computer will take a few moments to complete the POKEs.
As added insurance there is a checksum routine built into the pro-
gram. Type RUN, and the values in memory are checked. If an error
message appears, check the DATA statements. Block 1 includes lines
50 10-5050, block 2 includes lines 5060-5 100, and so on. If you find
a mistake, fix it and type RUN 60 followed by RUN. Remember to
save the final, debugged version.
There is one thing to watch out for. If you decide to use a single
line for your window, you can scroll left or right, but don't try to
move up or down. For example, if you set the top boundary to five
and the bottom to five, you can scroll line five to the left or to the
right. But try to scroll up and the computer crashes. And you can-
not escape the crash with RUN/STOP-RESTORE. You have to turn
your computer off and then on again (and lose whatever you have
in memory).
Smoother Scrolling
Regular scrolls move whole characters. It's like picking up a letter and
dropping it down one line.
The 64 can do smoother scrolls, moving characters a pixel at
a time. The key is memory locations 53270 (horizontal) and 53265
(vertical). To do smooth scrolls, use these formulas:
POKE 53270, (PEEK(53270)AND248) + X
POKE 53265, (PEEK(53265)AND248) + Y
X and Y can be any numbers from to 7. Once you've gone to
7 or 0, you'll have to do a regular scroll and reset the smooth scroll
to the other limit. Smooth scrolling can make an action game look
more realistic — the characters don't jump around, they slide.
A minor annoyance in this method is that while the screen is
doing a smooth scroll, you may see small gaps at the edges. You can
get around this by turning off bit 3 of these two registers; in the POKEs
above, AND with 240 instead of 248. In effect, you pull the border
in a notch, resulting in a 38 column by 24 row display (instead
of40 x25).
Because smooth scrolling affects the whole screen, it is not
compatible with Scroll 64 windows. If you combined the two, you
would see smooth scrolling inside the window and jittery, vibrating
173
4: Game Programming
characters outside the window. To fix this would require a high-res
screen, customized word sprites, or a raster interrupt wedge. All of
these are beyond the scope of this simple program.
Scroll 64
For mistake-proof program entry, be sure to read ' 'The Automatic Proofreader," Appendix C.
10 DATA11507, 12573, 12522, 11001 : rem 238
20 A=491 52 : B=84 : C=A+B : F0RI=1T04 : D=0 : READX : FORJ=ATO
C : D=D+PEEK ( J ) : NEXT : rem 236
30 IFD<>XTHENPRINTTAB( 19) "ERROR IN BLOCK #"I:G0T05
: rem 106
40 PRINT "BLOCK #"I"IS CORRECT" : rem 254
50 A=C+1:C=A+B: NEXT: END : rem 116
60 F0RI=1T04 : RE ADA : NEXT : READLO , HI : FORI=LOTOHI : READ
X:POKEI,X: NEXT: END :rem 125
5000 DATA 49152, 49528 :rem 28
5010 DATA 174,114,193,224,3,144,3,76,117,192,188,1
14,193,140,121,193,174 : rem 222
5020 DATA 118,193,232,202,32,30,193,172,121,193,17
3,119,193,201,2,208,10 : rem 198
5030 DATA 169,32,72,173,33,208,72,76,50,192,177,90
,72,177,92,72,204 :rem 252
5040 DATA 116,193,240,20,200,177,90,72,177,92,136,
145,92,104,145,90,200 : rem 166
5050 DATA 204, 116, 193, 208, 238, 240, 18, 136, 177, 90, 7^2
,177,92,200,145,92,104 :rem 230
5060 DATA 145,90,136,204,115,193,208,238,173,119,1
93,201,0,208,5,104,104 : rem 210
5070 DATA 76,111,192,104,145,92,104,145,90,236,117
,193,208,160,96,172,116 :rem 23
5080 DATA 193,200,189,114,193,170,32,30,193,173,12
0,193,201,2,208,19,136 : rem 214
5090 DATA 169,32,153,122,193,173,33,208,153,162,19
3,204,115,193,208,239,240 : rem 122
5100 DATA 16,136,177,90,153,122,193,177,92,153,162
,193,204,115,193,208,240 : rem 71
5110 DATA 236,117,193,240,37,202,32,30,193,172,116
,193,200,136,177,90,72 : rem 215
5120 DATA 177,92,32,48,193,145,92,104,145,90,32,56
,193,204,115,193,208 : rem 136
5130 DATA 234,236,117,193,208,221,240,46,202,206,1
18,193,232,32,30,193,172 :rem 53
5140 DATA 116,193,200,136,32,48,193,177,90,72,177,
92,32,56,193,145,92 : rem 96
5150 DATA 104,145,90,204,115,193,208,234,236,118,1
93,208,221,238,118,193,232 :rem 166
5160 DATA 32,30,193,173,120,193,201,0,240,20,172,1
15,193,136,200,185,162 :rem 194
174
Game Programming: 4
5170 DATA 193,145,92,185,122,193,145,90,204,116,19
3,208,240,96,189,89,193 :rem 54
5180 DATA 133,91,24,105,212,133,93,189,64,193,133,
90,133,92,96,72,152 : rem 88
5190 DATA 24,105,40,168,104,96,72,152,56,233,40,16
8,104,96,0,40,80 :rem 179
5200 DATA 120,160,200,240,24,64,104,144,184,224,8,
48,88,128,168,208,248 : rem 172
5210 DATA 32,72,112,152,192,4,4,4,4,4,4,4,5,5,5,5,
5 :rem 173
5220 DATA 5 , 6 , 6 , 6 , 6 , 6 , 6, 6 , 7 , 7 , 7 , 7 , 7 , 3 ,0,4,0 :rem 44
5230 DATA 4,1,1 :rem 210
175
Dan Carmichael and Tom R. Halfhill
Reader
One of the articles in the
premier issue of COM-
PUTED Gazette was a
paddle reader routine for
the Commodore 64. The
idea was to reduce the
"jitter" in screen objects
controlled by the game
paddles. This jittering is caused by minor fluctuations in the paddle's
readings. To calm down the jitter, Bobby Williams wrote a short
machine language routine which read the paddle 256 times in a split
second, averaged the readings, and used the average for a final
paddle value.
The routine worked fine, but some readers wanted more. The
original routine was for one paddle only, ignoring the second paddle.
The result of these readers' requests is this new and improved rou-
tine. It is still a machine language program, still POKEd into memory
by a BASIC loader so that you don't need to know anything about
ML to use it, and it still reduces the paddle jitters. But now it works
with two controllers instead of only one.
A BASIC Loader
As before, you don't have to know anything about machine language
to use this routine. It's in the form of a BASIC loader — a short BASIC
subprogram which you add to your own BASIC programs. Using the
POKE statement, it loads decimal numbers into memory which
correspond to the proper machine language commands.
The program is stored in a normally safe area of memory, the 88
bytes from address 679 to 710 (decimal). This is not the same area
where the previous paddle reader routine was stored. The earlier
routine was stored in an often-used block of memory that we've
decided to preserve for other purposes.
Be sure to type in the program correctly, and as always when
dealing with machine language, SAVE the program before the first
RUN. This allows you to recover your work in case of a typing error
that crashes the computer.
Reading the Paddles
Once the routine is added to your BASIC program, it must be activated
with a SYS statement each time you want to read the paddles. To
start the routine, use SYS 679.
64 Paddle
An enhancement of a program
which first appeared in the July
1983 issue of COMPUTE! 's
Gazette, this game utility reads
two paddles and reduces the
"jitters " commonly experienced
with these game controllers.
176
Game Programming: 4
You then read the paddles with a simple PEEK statement. To get
the averaged reading of paddle 1, use PEEK(251); for paddle 2, use
PEEK(252). Here's an example:
10 SYS679:P1=PEEK(251) :P2=PEEK(252)
20 PRINTP1; :PRINTP2
30 GOTO10
Note that these locations are different from the usual paddle
locations. That's because the routine stores the averaged readings
at 251 and 252, not at the customary locations (that is, 54297 on
the Commodore 64).
The short program above displays the values found at the paddle
locations. Plug the paddles into port 1. As you move the paddle
knobs, the values will change. Note that each time you read the
paddles, you must use the SYS 679 command.
64 Paddle Reader
For mistake-proof program entry, be sure to read "The Automatic Proofreader, "Appendix C.
10 FORA=679 TO 710: READB : POKEA , B : NEXT :rem 208
679 DATA 169,0,170,168,24,109,25 : rem 54
686 DATA 212,144,1,200,202,208,247 t rem 130
693 DATA 132,251,138,168,24,109,26 :rem 149
700 DATA 212,144,1,200,202,208,247 :rem 117
707 DATA 132,252,96,0 :rem 10
177
Charles Bond
Translated to machine language by Gary E. Marsa and for the 64 by Gregg Peele.
Maze Generator
This program, although quite "Maze Generator" is a
short, creates a totally random remarkably short algorithm
maze display every time it's run. which produces random
Use it as the basis for any maze mazes on Y our television set
game you 'd like to design. or monitor. There are two
versions of the program
included here. The first, in BASIC, may seem shorter and easier to type
in, but if you compare it to the second program, you'll see how slow
it is. Program 2 is a machine language program. In the form of a
BASIC loader which POKEs the data into your computer's memory,
it creates mazes almost instantly. This is a good example of how fast
machine language is, compared to BASIC.
The BASIC version of the program has also been included to
better explain how the maze generator works. It's difficult, if you
aren't familiar with machine language, to understand what each
value POKEd into memory does. For those of us who are more com-
fortable with BASIC, it's much easier to see how that version operates.
Refer to Program 1 and the flowchart figure as the program's
details are explained. You can use either Program 1 or Program 2
to see how the mazes are created. You can even use either version
as part of your own game program. However, remember that the
machine language version executes much faster. If you use the ML
version (Program 2), a player would have to wait only a moment.
Since Program 2 is in the form of a BASIC loader, SAVE it before you
try to run it. If you enter the data incorrectly, the computer could
crash, and you'd have to retype the entire listing unless it had been
previously saved on tape or disk.
The Background Field
The algorithm operates on a background field which must be gener-
ated on the screen prior to line number 210 in Program 1. The field
must consist of an odd number of horizontal rows, each containing
an odd number of cells — in other words, a rectangular array. It's
convenient to think of the field as a two-dimensional array with the
upper-left corner having coordinates X = and Y = 0, where X is
the horizontal direction and Y is vertical. No coordinates are used to
identify absolute locations by the program, but the concept is useful
in configuring the field.
178
Game Programming: 4
Given that the upper-left cell of the field has coordinates 0,0,
then the terminal coordinates both horizontally and vertically must
be even numbers. (Remember that there is an odd number of rows
and columns.) In addition, the background field must be surrounded
on all sides by memory cells whose contents are different from the
number used to identify the field. That is, if the field consists of
reverse video spaces, the number corresponding to that character
must not be visually adjacent to the field.
This could happen inadvertently if the screen RAM and system
ROM have contiguous addresses. A sufficient precaution is to avoid
covering the entire screen with field. Leave at least one space at the
beginning or end of each line and, in general, leave the uppermost
and lowermost lines on the screen blank.
The Maze Generator
The creation of the maze begins by placing a special marker in a
suitable starting square. The program here always begins at the square
just inside the upper-left cell of the previously drawn field. (Note
that with our coordinate scheme this would be cell 1,1.) Any cell with
odd-numbered coordinates would work, however, as long as it is
internal to the field.
Next, a random direction is chosen by invoking the random
number generator in the computer and producing an integer from
to 3 . This integer, with the aid of a short table, determines a direction
and a corresponding cell just two steps away from the current cell.
This new cell is examined (PEEKed) to see if it is part of the field. If
it is, the direction integer is put there as a marker, and the barrier
between it and the current cell is erased.
In addition, the pointer to the current cell is moved to point to
the new one. This process is repeated until the new cell fails the test;
that is, it is not a field cell. When this happens, the direction vector
is rotated 90 degrees and the test is repeated. Thus, the path carved
out of the field will continue until a dead end is reached.
A dead end, incidentally, could occur in as few as five steps.
When it does occur, we can make use of the markers which were
dropped along the way Hansel-and-Gretel style. These can be checked
to determine which direction we came from, so that we can back up
and look for untrodden paths. So long as none can be found, the pro-
gram will back up, one step at a time, erasing the markers as it goes.
When a new direction can be taken, the pointer is set off in that
direction, and the process continues as before.
179
4: Game Programming
Ultimately, the pointer will return to the start, a condition which
is detected by the recovery of the special starting (now "ending")
marker. This cell is then blanked and the program is done, leaving the
pointer as it was at the start.
The Program
The direction table set up in lines 100 and 110 of Program 1 converts
an integer to an address offset. In this case (40-column screen), we
wish to step two cells to the right, up, left, or down.
Line 120 contains the variable SC, which is the memory address
of the start of screen RAM. Lines 130- 160 establish the background
field on the screen.
The rest of the program draws the maze, as previously explained.
Line 310 is simply a convenient stopping point which prevents the
screen from scrolling.
It may not be immediately obvious that this algorithm always
produces a maze with only one nontrivial path between any two
points, or that the maze will always be completely filled, but this can
be proved. While the proofs will not be provided here, math buffs
may find it interesting that for a maze of any size there will be exactly:
(H-lXV-l) , empty cells in the completed maze
2
where H is the number of cells in each field row and V is the number
of rows.
An interesting feature of this algorithm is that it works equally
well in certain types of nonrectangular fields. U-shaped fields or
fields with holes in them are quite suitable — as long as certain
restrictions are observed. Just make sure that the coordinates of the
upper-left and lower-right cells of any cut-out area are pairs of odd
numbers. Also, if there is a single row of field cells between any cut-
out areas and the outside of the original field, it may be removed.
Machine Language Mazes
Program 2 is a machine language translation of Program 1. It is in the
form of a BASIC loader. It can be inserted into any BASIC program
just as Program 1.
Program 3 is the disassembly listing of the machine language
routine found in Program 2.
The Mouse
The subroutine on lines 1000 to 1020 of Program 1 produces an
artificial mouse which roams the maze endlessly. The mouse adheres
180
Game Programming: 4
to a "left-hand rule" when a choice of directions is possible. That
is, when it is confronted with a branch-point, it will move off to the
left, if possible. Otherwise, it will go forward. When no choice is
available it will turn around. These lines are unnecessary for the crea-
tion of the maze and may be deleted. Program 2 does not contain
the mouse.
Program 1. BASIC Maze Generator
For mistake-proof program entry, be sure to read "We Automatic Proofreader,' 'AppendixC.
100
DIMA(3)
:rem 48
110
A(0)=2:A(1)=-80:A(2)=-2:A(3)=80
:rem 208
120
WL=160 :HL=32 :SC=1024 :A=SC+81
:rem 48
130
PRINT" {CLR}"
:rem 248
140
F0RI=1T023
:rem 59
150
PRINT" {RVS} {WHT} { 39 SPACES}"
:rem 126
160
NEXT I
: rem 31
210
P0KEA,4
:rem 99
220
J=INT(RND(1)*4) :X=J
: rem 52
230
B=A+A(J) :IF PEEK ( B ) =WLTHENP0KEB , J : POKEA+A ( J ) /2
,HL:A=B:GOTO220
:rem 166
240
J=( J+1)*-(J<3) :IFJOXTHEN230
: rem 30
250
J=PEEK(A) :P0KEA,HL:IFJ<4THENA=A-A(J) :GOTO220
: rem 192
310
GETC$ :IFC$=" "THEN310
: rem 79
1000 POKEA,81:J=2 : rem 185
1010 B=A+A( J)/2:IFPEEK(B)=HLTHENPOKEB,81:POKEA,HL:
A=B:J=( J+2)+4*( J>1) :rem 33
1020 J=(J-1)-4*(J=0) :GOTO1010 : rem 11
Program 2. Machine Language Maze Generator
For mistake-proof program entry, besuretoread "The Automatic Proofreader," AppendixC.
10 1=49152 :IF PEEK ( 1+2 )=216THENSYS49160 : END
20 READ A: IF A=256 THENSYS49160 : END
30 POKE I,A:I=I+1:G0T0 20
49152 DATA 1,0,216,255,255,255,40
49160 DATA 0,169,81,133,251,169,40
49168 DATA 133,253,169,4,133,252,133
49176 DATA 254,169,147,32,210,255,162
49184 DATA 0,160,0,169,160,145,253
49192 DATA 200,192,39,208,249,24,165
49200 DATA 253,105,40,133,253,144,2
49208 DATA 230,254,232,224,23,208,229
49216 DATA 160,0,169,4,145,251,169
49224 DATA 255,141,15,212,169,128,141
49232 DATA 18,212,173,27,212,41,3
49240 DATA 133,173,170,10,168,24,185
49248 DATA 0,192,101,251,133,170,185
49256 DATA 1,192,101,252,133,171,24
:rem 234
:rem 230
:rem 130
:rem 89
: rem 146
: rem 250
: rem 49
:rem 142
:rem
: rem 177
: rem 36
: rem 1 49
:rem 37
: rem 85
:rem 243
: rem 240
: rem 186
181
4: Game Programming
49264 DATA 185,0,192,101,170,133,253 :rem 240
49272 DATA 185,1,192,101,171,133,254 : rem 242
49280 DATA 160,0,177,253,201,160,208 :rem 237
49288 DATA 18,138,145,253,169,32,145 :rem 9
49296 DATA 170,165,253,133,251,165,254 :rem 100
49304 DATA 133,252,76,62,192,232,138 :rem 250
49312 DATA 41,3,197,173,208,189,177 :rem 212
49320 DATA 251,170,169,32,145,251,224 :rem 35
49328 DATA 4,240,26,138,10,168,162 : rem 147
49336 DATA 2,56,165,251,249,0,192 :rem 103
49344 DATA 133,251,165,252,249,1,192 :rem 250
49352 DATA 133,252,202,208,238,76,62 :rem 249
49360 DATA 192,169,1,160,0,153,0 .-rem 37
49368 DATA 216,153,0,217,153,0,218 :rem 144
49376 DATA 153,0,219,200,208,241,96,256 : rem 143
Program 3. Source Listing
C000
01
00
C002
D8
C003
FF
C004
FF
C005
FF
C006
28
C007
00
C008
A9
51
LDA
#$51
C00A
85
FB
STA
$FB
C00C
A9
28
LDA
#$28
C00E
85
FD
STA
$FD
C010
A9
04
LDA
#$04
C012
85
FC
STA
$FC
C014
85
FE
STA
$FE
C016
A9
93
LDA
#$93
C018
20
D2 FF
JSR
$FFD2
C01B
A2
00
LDX
#$00
C01D
A0
00
LDY
#$00
C01F
A9
A0
LDA
#$A0
C021
91
FD
STA
($FD),Y
C023
C8
I NY
C024
C0
27
CPY
#$27
C026
D0
F9
BNE
$C021
C028
18
CLC
C029
A5
FD
LDA
$FD
C02B
69
28
ADC
#$28
C02D
85
FD
STA
$FD
C02F
90
02
BCC
$C033
C031
E6
FE
INC
$FE
C033
E8
INX
C034
E0
17
CPX
#$17
C036
D0
E5
BNE
$C01D
182
C038 A0 00
C03A A9 04
C03C 91 FB
C03E A9 FF
C040 8D 0F D4
C043 A9 80
C045 8D 12 D4
C048 AD IB D4
C04B 29 03
C04D 85 AD
C04F AA
C050 0A
C051 A8
C052 18
C053 B9 00 C0
C056 65 FB
C058 85 AA
C05A B9 01 C0
C05D 65 FC
C05F 85 AB
C061 18
C062 B9 00 C0
C065 65 AA
C067 85 FD
C069 B9 01 C0
C06C 65 AB
C06E 85 FE
C070 A0 00
C072 Bl FD
C074 C9 A0
C076 D0 12
C078 8A
C079 91 FD
C07B A9 20
C07D 91 AA
C07F A5 FD
C081 85 FB
C083 A5 FE
C085 85 FC
C087 4C 3E C0
C08A E8
C08B 8A
C08C 29 03
C08E C5 AD
C090 D0 BD
C092 Bl FB
C094 AA
C095 A9 20
C097 91 FB
LDY
#$00
LDA
#$04
STA
( $FB) . Y
LDA
#$FF
O X A
$D40F
T r>A
LlL/tx
TT y OKI
STA
$D412
LDA
$D41B
AND
#$03
STA
$ AD
TAX
ASL
TAY
CLC
LDA
$C000,Y
ADC
$FB
STA
$AA
LDA
$C001 . Y
ADC
T*
O J- A
SAR
CLC
LDA
$C000, Y
$AA
STA
$FD
LDA
$C001 . Y
ADC
$AB
STA
$FE
LDY
#$00
LDA
( $FD) , Y
CMP
#$A0
BNE
$C08A
TXA
STA
( $FD) . Y
LDA
#$20
STA
( $AA) , Y
LDA
$FD
STA
$FB
LDA
$FE
STA
$FC
JMP
$C03E
I NX
TXA
AND
#$03
CMP
$AD
BNE
$C04F
LDA
($FB),Y
TAX
LDA
#$20
STA
($FB),Y
4: Game Programming
C099
E0
04
CPX
#$04
C09B
F0
1A
BEQ
$C0B7
C09D
8A
TXA
C09E
0A
ASL
C09F
A8
TAY
C0A0
A2
02
LDX
#$02
C0A2
38
SEC
C0A3
A5
FB
LDA
$FB
C0A5
F9
00
C0
SBC
$C000,Y
C0A8
85
FB
STA
$FB
C0AA
A5
FC
LDA
$FC
C0AC
F9
01
C0
SBC
$C001,Y
C0AF
85
FC
STA
$FC
C0B1
CA
DEX
C0B2
D0
EE
BNE
$C0A2
C0B4
4C
3E
C0
JMP
$C03E
C0B7
A9
01
LDA
#$01
C0B9
A0
00
LDY
#$00
C0BB
99
00
D8
STA
$D800 f Y
C0BE
99
00
D9
STA
$D900,Y
C0C1
99
00
DA
STA
$DA00,Y
C0C4
99
00
DB
STA
$DB00,Y
C0C7
C8
I NY
C0C8
D0
Fl
BNE
$C0BB
C0CA
60
RTS
184
Game Programming. 4
Maze Generator Flow Chart
BACK UP
VALID \ VES
DIRECTION?
LEAVE MARKER,
ERASE BARRIER,
BUMP POINTER
Chris Metcalf
Multiple-Key
Scanner
This routine, located at
address 828, allows a pro-
gram to input several keys
simultaneously from the
keyboard. In a two-player
keyboard action game, this
can be crucial, since both
moves should be evaluated
simultaneously. This sub-
routine can serve other
uses, too; it was originally
developed to allow chords to be struck on the keyboard and be
interpreted as chords, rather than single notes.
To use the routine, enter a SYS 828. The result of this SYS is to
place the ASCII values of all the keys that are being pressed at that
moment in the keyboard buffer, where they can be read with GET
statements. For example, if two keys were being held down, 5 and I,
and a SYS 828 is executed, s and / are placed in the keyboard buffer.
Two GET statements would retrieve them; any further GETs would
return " ", the null string. Up to ten characters can be interpreted in
this fashion.
Not Perfect
However, the routine is not perfect. It really can't be. Commodore did
not design the keyboard to be used in this fashion, so multiple-key
reading does not always return the correct keys. As far as I know, any
two keys are reported accurately; most (but not all) three-key com-
binations seem to work. As you get to four and above, unfortunately,
extraneous characters begin to be reported. Another problem is that
BASIC itself is always watching for keys being pressed. Because of this,
two copies of one of the keys are sometimes reported when it is
first pressed.
One feature of this routine is that it will continue to return the
keys pressed, even if the routine is called several times. Thus you
cannot only tell when a key is pressed, but also when it is released.
Each SYS 828 loads the buffer with the keys currently pressed,
regardless how many times the keys have been reported.
Writing two-player games can
be difficult. One of the problems
is figuring out how to allow
input by both players. Although
there's a two-joystick routine
included in this book, you may
not have (or want to use) joy-
sticks. Here's a short routine
which allows both players to use
the keyboard at the same time.
186
Game Programming: 4
Special Codes
Another feature of this routine is that it returns not only ASCII values
for all the keys (including function keys, cursor keys, and so forth),
but it also returns special codes to indicate when left-SHIFT, right-
SHIFT, Commodore, or CTRL keys are depressed. CHR$(1) for the
left-hand SHIFT key and SHIFT LOCK, CHR$(2) for the right-hand
SHIFT, CHR$(3) for the Commodore key, and CHR$(4) for the CTRL
key are returned. This routine also removes the effects of SHIFT or
Commodore on other keys. For instance, if SHIFT-3 is pressed, SYS
828 returns a CHR$(1) or CHR$(2) along with the code for 3, not
simply the code for #.
Enter and Demonstrate
Program 1, "Keyscan," is a machine language program. Its data is
POKEd into the cassette buffer (starting at location 828) by the BASIC
loader (lines 10-30). Save the program before you first run it. That
will prevent the loss of your typing time if you've entered it incor-
rectly and the computer locks up.
You can add this program to your own game, simply by chang-
ing the line numbers (to 60000 and up, for example), adding a
RETURN to its end, and then calling the subroutine with a GOSUB.
Once the data has been placed in memory, you access the routine
by SYSing 828. Of course, you'll also need to place a GET A$ (or
something similar) in your program to retrieve the characters that
the routine puts in the keyboard buffer. (See Program 2 for an
example of this.)
Program 2, "Demo/Scan," is a BASIC program which shows you
what Keyscan can do. Make sure you've loaded and run Keyscan,
then load and run Program 2. It prints out the characters received
from SYS 828. You can get a good idea of the power and limitations
of the Keyscan routine by testing various combinations of keys.
Since Keyscan occupies the cassette buffer (locations 828-1019),
it will be erased when you load from or save to your Datassette. If
that happens, you'll have to reload and rerun the routine to place the
machine language data back in memory.
Program 1. Keyscan
For mistake-proof program entry, be sure to read ' 'The Automatic Proofreader, "Appendix C.
10 P0RI=828 TO 959:READA:POKEI,A:NEXT : rem 233
20 CK=CK+1 :IFCK<>1 THEN PRINT "ERROR IN DATA"
30 END
828 DATA 120,169,000,133,198,170
834 DATA 169,254,141,000,220,172
:rem 84
:rem 58
:rem 44
:rem 36
187
4: Game Programming
840
DATA
001,220,148
,088,232,056
: rem
38
846
DATA
042. 176. 243
.162.007.160
• rem
44
852
DATA
007,181,088
,106,176,027
: rem
52
858
DATA
072. 132 . 002
.138.010.010
: rem
26
864
DATA
010. 005 . 002
.168 . 185 . 125
• rem
37
870
DATA
003 . 164 . 198
. 153 . 119 .002
; rem
43
876
DATA
192,010,240
,011,230,198
: rem
39
882
DATA
104. 164. 002
, 136,016,223
: rem
34
888
DATA
202 . 016 . 216
. 088 . 096 .017
: rem
57
894
DATA
135. 134. 133
.136.029.013
: rem
44
900
DATA
020,001,069
,083,090,052
: rem
28
906
DATA
065,087,051
,088,084,070
: rem
56
912
DATA
067,054,068
,082,053,086
: rem
54
918
DATA
085,072,066
,056,071,089
: rem
62
924
DATA
055,078,079
,075,077,048
: rem
68
930
DATA
074,073,057
,044,064,058
: rem
50
936
DATA
046,045,076
,080,043,047
: rem
50
942
DATA
094,061,002
,019,059,042
: rem
41
948
DATA
092,005,081
,003,032,050
: rem
33
954
DATA
004,095,049
,013,013,013
: rem
35
Program 2. Demo/Scan
Fc^mistake-proofpmgmmentry,besuretoread''TyeAutomaticPwofivader,''AppendixC.
10 PRINT "HOLD DOWN KEYS IN VARIOUS COMBINATIONS"
:rem 19
20 PRINT "TO GET A FEEL FOR THE ROUTINE." : rem 47
30 PRINT "NOTE THAT SHIFT AND COMMODORE DO NOT"
: rem 21
40 PRINT "AFFECT OTHER KEYS BUT GENERATE CODES OF"
:rem 213
50 PRINT "THEIR OWN INSTEAD. {DOWN} " : rem 237
100 SYS(828):REM STUFF GET-BUFFER : rem 240
110 GETA$ : IFA$=" "THEN100 : rem 70
120 POKE216,l:PRINTA$; : rem 31
130 GETA$:IFA$O""THEN120 :rem 135
140 PRINT :GOTO100 : rem 38
188
Chapter 5
Applications
and Utilities
□
□
□
□
□
D
□
Glen Colbert
String Search
Data management programs Have you ever had to search
often use string arrays to store through a string array to
information. Retrieving that find a certain occurrence of
information can be time- a strin 8 ? If Y ou have, I'm
consuming, however, if you have surc * hat y° u csm *f f°
to rely on BASIC. This machine Sl °^ S ni ^ a BA n ro
language routine searches an ^^eeps Kkof "
entire array for your designated ° ddresses and bills . The
string and even returns a flag program used to f or -
to mark its place. ever to f mc i a string match.
The solution was to
use a short machine language program that would do the search and
return a flag to the BASIC program. I found Ronald A. Blattel's "PET
Searcher" in the April 1983 issue of COMPUTE! magazine and began
converting the addresses so that it would run on my computer. But
after running the converted version a few times, I decided that it was
too clumsy. Each time a match was made, control returned to BASIC
and the search routine had to be restarted with the USR function. I
wanted to be able to scan forward and backward through the matched
strings, so I had to build an array and set a flag in a matching element
each time the program returned from the routine.
I was using memory space for an array already and I had to
check against that array in BASIC to see if there was a match. A more
efficient way of doing the search would be to have the ML routine
set the flags in the other array while it was working on the search.
Thus, when the program returned to BASIC, the checking array
would be ready.
Zero Page Swap
This routine utilizes one string variable for matching against the
array, a string array which contains the information to be checked,
and an integer array to keep track of which elements in the string
array match the string variable. It was written without internal JMPs
or JSRs so that it can be relocated anywhere in memory. In general,
the routine is very dependable. However, there are two things that
you must take into consideration when using it: First, it swaps out a
section of the zero page into the cassette buffer, and second, the
pointers to the variables must be where the routine expects them.
Anyone who has done any machine language programming on
191
5: Applications and Utilities
the 64 knows just how limited free space in zero page is. To get
around this, the routine moves apart of the zero page into the cassette
buffer to make room. Once the routine is finished with the zero
page work space, it moves the data from the buffer back where it
belongs. Normally this is not a problem, but if there are other ML
routines or unprocessed data in the cassette buffer, the routine will
write over them.
Picky Variables
The variables must be initialized in the correct sequence to place
them in memory locations where the routine can look for them. The
first and second variables defined in the program must be strings
(for example, A$ = " " and B$ = " "). The string variable that you want
to check for must be the second variable. The string array to be
searched mustbe the first array DIMensioned. The integer array must
be the second array DIMensioned. All of this has to be done before
the routine is called. (Look at Program 2, lines 20-40, for an example
of the proper way to initialize these variables.)
Pointers and Counters
The search method used is quite simple. When it's called, the first
operation is to swap out a portion of the zero page locations $D9 to
$E9, in hexadecimal. The length of the string to be checked for is put
into location $D9 and the address of the string is set into locations
$DA-S5DB. Next, addresses $DC-$DD are set to point to the element
of the integer array. Addresses $E0-$E1 are set to point to the three
bytes of string array information (length, low byte of address, and high
byte of address) for the element of the string array. Things are now
ready for the processing loop.
The first step in the processing loop is to increment the pointers
for the arrays to the next element. For this reason, the element is
not searched. The information for the string array element being
worked is moved to locations JJE5- $E7. Address $E5 is checked for
a (string = " ") and if so, swaps the zero page information back in and
returns to BASIC. A counter for the search string ($E2) and one for the
searched string ($E3) are set to zero and the search begins.
If the search string counter is equal to the length of the search
string, there has been a match. If the searched string counter is
equal to the length of the searched string, there was no match. On
either event, the routine sets the value in the integer array and
returns to the main loop to try the next element of the array.
If the counters do not match, the accumulator is loaded with the
192
Applications and Utilities: 5
first character of the search string. This is compared against each
element of the searched string until a match is found. Then the second
character of the search string is compared against the next character
in the searched string and so on until the counter equals the length
of the search string. If a match is not found, the search string
counter is reset (but not the searched string counter) and the program
loops back.
Machine Language Speed
Using "String Searcher" is not as complicated as you might think.
Type in and save Program 1. This is a BASIC loader which POKEs in
the machine language routine. Once it's in memory, you can access
it by this command:
SYS(PEEK(5 5) + 2 56 * PEEK(56))
Inserting that command in your program allows you to use the search
function. Remember, however, the restrictions on variable place-
ment that were explained earlier. The first two variables defined in
your program must be string variables, with the second being the
string you want to check for. The string array must be the first array
DIMensioned, and the integer array must be the second array DIMed.
Running your program, making sure the above SYS command is
included, will search through the entire string array and flag any
occurrence of the string you selected to check for. The integer vari-
able will contain a 1 if the string was found, a if it was not found.
All you have to do, then, is PRINT all the strings that do not equal 0.
That's your list of the strings which contain the item(s) you were
looking for.
Program 2 is a good example of all this. Notice that the variables
are set in the correct form and order in lines 20-40. The string to be
checked, Q$, is set in line 30, while the string and integer arrays are
DIMed in line 40. Three hundred strings are built and put into the
A$(L) array, and each string is searched for Q$, which has been set
equal to "GOOD" in line 110. Note that five strings in the array (lines
170-195) have been set to include that word. This, of course, is for
demonstration purposes. If you were using String Searcher in your
own program, you would already have strings set that you would
want to search through.
Make sure you have Program 1 loaded and run. Then load and
run Program 2 . The string array is built, and two searches are done.
The first is with a BASIC program. Once it's finished, it will tell you
how long it took and display the strings that included the word you
checked for. The machine language routine then searches through the
193
5: Applications and Utilities
same string array, again displaying the time used and the strings
found. Notice the difference in time. The speed of machine language
is clearly demonstrated.
Lines 390 and 450 decide which strings to display. If the integer
variable Q% for a particular string does not equal (in other words,
if it is a 1), the word searched for was included in that string, and it's
printed on the screen. You can use the same process in your own
programs to see which strings include the item(s) you checked for.
Program 1. String Searcher BASIC Loader
For mistake-proof program entry', be sure to read "The Automatic Proofreader," Appendix C.
100 PRINT" {CLR} {4 DOWN} {12 SPACES } STRING SEARCHER"
:rem 93
110 PRINT" {2 DOWNjONE MOMENT PLEASE" : rem 241
120 TP=PEEK(55)+256*PEEK(56) :rem 39
130 TP=TP-186:H=INT( (TP)/256) :L=TP-H*256 : P0KE55 , L:
POKE56,H :rem 215
140 IN=PEEK(55)+256*PEEK(56) :FORC=IN TO IN+185:REA
DI:POKEC, I:CK=CK+I:NEXT: :rem 209
150 IFCK<>26449 THEN PRINT "ERROR IN DATA " : END
:rem 130
160 REM****************** STRING SEARCH DATA******
**************** : rem 178
180 DATA 160,17,185,216,0,153,60,3,136,208 :rem li
190 DATA 247,160,9,177,45,133,217,200,177,45
:rem 128
200 DATA 133,218,200,177,45,133,219,24,160,2
:rem 102
210 DATA 177,47,101,47,105,7,133,220,200,177
:rem 105
220 DATA 47,101,48,133,221,160,0,24,165,47 :rem 3
230 DATA 105, 7, 133, 224, 165, 48, 105,0, 133, 225:rem 53
240 DATA 169,0,240,12,160,17,185,60,3,153 :rem 212
250 DATA 216,0,136,208,247,96,24,165,224,105
:rem 118
260 DATA 3,133,224,165,225,105,0,133,225,160
:rem 98
270 DATA 0,177,224,153,229,0,200,192,3,208 :rem 7
280 DATA 246,24,165,220,105,2,133,220,165,221
: rem 150
290 DATA 105,0,133,221,165,229,240,202,208,2
:rem 98
300 DATA 240,210,162,0,134,227,134,226,24,165
:rem 146
310 DATA 217,197,226,240,31,24,165,229,197,227
:rem 228
320 DATA 144,37,164,226,177,218,164,227,209,230
:rem 19
194
Applications and Utilities: 5
330 DATA 208,6,230,227,230,226,208,226,230,227
:rem 207
340 DATA 169,0,133,226,240,218,160,0,169,1 : rem 7
350 DATA 145,220,200,169,0,145,220,240,197,160
:rem 202
360 DATA 0,152,145,220,240,242 :rem 179
999 PRINT "DONE": NEW :rem 198
Program 2. Timed Search
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
20 A$=" DUMMY DATA": REM {2 SPACES} MUST BE A STRING
:rem 244
30 Q$="":REM THIS IS TO BE USED AS THE SEARCH STRI
NG :rera 168
40 DIMA$ ( 300 ) , Q% ( 300 ) : REM SEARCHED STRING AND FLAG
ARRAY :rem 173
45 ML=PEEK(55)+256*PEEK(56) :REM START ADDRESS
:rem 164
100 PRINT "BUILDING ARRAY
110 Q$="GO0D"
120 F0RL=1T0299
130
! A$ ( L ) = " ABCDEFGHIJKLMNOPQRSTUVWXYZ
140
150
160 NEXTL
170 A$ ( 1 )= "GARBAGE GOOD MORE GARBAGE"
180 A$(10)="GARB GOOD MORE GARB"
185 A$(70)="GOOD GARBAGE"
190 A$(100)="GARBAGE GOOD"
195 A$ ( 250 )= "GARBAGE GOOD MORE GARBAGE"
200 PRINT "ARRAY FINISHED"
300 REM {2 SPACES} BASIC SEARCH
310 PRINT"BASIC SEARCH" :TI$=" 000000"
320 F0RL=1T0299
330 : FORJ=lTOLEN ( A$ ( L ) ) -LEN ( Q$ ) +1
340 : :IFMID$(A$(L) , J,LEN(Q$) )=Q$THENQ%(L)=
350 : NEXT J
360 NEXTL
370 PRINTTI; "JIFFIES"
380 FORL=lT0299
390 :IFQ%(L) <>0THENPRINTA$(L)
395 NEXTL
400 REM {2 SPACES} ML SEARCH
410 PRINT "ML SEARCH" :TI$="000000"
420 SYS (ML)
430 PRINTTI ; "JIFFIES "
440 F0RL=1T0299
450 : IFQ% (L) <>0THENPRINTA$ (L)
460 NEXTL
:rem 47
:rem 177
:rem 123
: rem 206
: rem 49
:rem 208
:rem 34
:rem 46
:rem 197
:rem 78
:rem 116
:rem 155
:rem 44
:rem 143
:rem 25
:rem 125
:rem 114
1: NEXTL
:rem 89
:rem 91
:rem 36
: rem 67
:rem 131
:rem 224
:rem 44
:rem 199
:rem 81
:rem 127
:rem 64
:rem 128
:rem 221
:rem 37
195
John W. Ross
Ultrasort
This is probably the fastest "Ultrasort" is a sequel. Sort
sorting program ever published II, I could have called it. It's
for a home computer. It can an improved, faster version
alphabetize 1000 items in less of a program first published
than eight seconds. Included is in the February 1983 issue
the BASIC loader to place the of COMPUTE! magazine. In
program in memory, as well ^^Cw/CW'l
as a demonstration thatletsyou desC ribed a shell sort for t'he
seehow Ultrasort works. C BM 8032 written entirely
in machine language. It worked as expected and was, overall, quite
fast. But it had a couple of shortcomings. First of all, it had a clumsy
interface with BASIC; that is, the calling sequence was not very effi-
cient. Second, the sorting was performed by a shell short algorithm.
This method of sorting, although faster than some other types of
sorts, is not the best available.
C.A.R. Hoare's Quicksort algorithm is possibly the fastest yet
developed for most applications. So I rewrote my machine language
sort program based on the Quicksort algorithm.
Speed Improvements
How much better is it? In order to test the program, I wrote a small
sort test program (Program 2), similar to the one in my original
article. This program generates a character array containing N items
(line 110).
Different items are generated, depending on the value of the
random number seed, SD in line 140; SD must be a negative number.
I generated six 1000-element arrays and sorted them using both
the shell sort and Ultrasort. Super Shell Sort required an average of
29.60 seconds to sort all 1000 elements, while Ultrasort required an
average of only 8.32 seconds. The sorting time has decreased over
300 percent. I don't believe you will find a faster sort for an eight-bit
machine anywhere.
The way you start the sort (see Program 2) has also been refined.
To run the sort, you simply type:
SYS 49152,N,AA$(K)
Running the Program
Ultrasort can be used either from within a program or in immediate
mode. Running Ultrasort causes N elements from array AAJ5, starting
with element K, to be sorted into ascending order. The sort occurs
196
Applications and Utilities: 5
in place; there is no additional memory overhead. N and K can be
constants or variables, and any character array name can be sub-
stituted for AA$.
Before running the sort, though, it must be loaded by BASIC. The
appropriate loader is supplied in Program 1. The tradeoff for the
increased speed of Ultrasort is increased complexity, especially in
machine language. The sort program starts at location 49152 (5JC000)
on the 64 . The increased size, of course, creates a greater possibility
of errors when you enter the numbers. In order to minimize this,
make sure you read and use "The Automatic Proofreader," Appendix
C. This program makes it simple to enter Ultrasort correctly the first
time. It's important that you save a copy of Ultrasort before you try
to run it. One error can make the computer lock up, and if you haven't
saved it first, you might lose all of your typing.
You can add Ultrasort to the end of your own program if you like ,
simply by changing the first three line numbers (perhaps to 49100,
49110, and 49120), then typing it in as you enter your own program.
Or you can use Ultrasort in immediate mode.
Program 2 is a short demonstration that shows how to use
Ultrasort, as well as how fast the sorting process really is. To see this
demonstration, first load and run Ultrasort. Type NEW, then load
and run Program 2, "Sort Test." One hundred random strings will be
created for you, and after you press any key, they'll be sorted. You
can see them displayed in alphabetical order by pressing any other
key. The time taken to sort the strings is displayed at the end of the
listing. You can change the number of strings created and sorted by
altering the value of N in line 110 of Program 2.
Ultrasort is fast. It will sort 100 strings in about half a second.
One thousand strings can be sorted in less than eight seconds. You'll
find this program the fastest sort available for the 64, and one that
you'll use again and again to sift through lists.
Program 1. Ultrasort
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
10 1=49152 :rem 236
20 READA: IFA=256THENEND : rem 169
30 P0KEI,A:I=I+1 :GOTO20 :rem 130
49152 DATA76, 100, 192, 170, 170, 170, 170 : rem 33
49159 DATA170,170,170,170,170,170,170 : rem 86
49166 DATA170,170,170,170,170,170,170 : rem 84
49173 DATA170,170,170,170,170,170,170 : rem 82
49180 DATA170,170,170,170,170,170,170 :rem 80
49187 DATA170,170,170,170,170,170,170 : rem 87
49194 DATA170,170,170,170,170,170,170 :rem 85
197
5: Applications and Utilities
49201 DATA170,170,170,170,170,170,170 : rem 74
49208 DATA170, 170,170,170,170,170,170 : rem 81
49215 DATA170,170,170,170,170,170,170 : rem 79
49222 DATA170,170,170,170,170,170,170 :rem 77
49229 DATA170,170,170,170,170,170,170 :rem 84
49236 DATA170,170,170,170,170,170,170 : rem 82
49243 DATA170,170,170,170,170,170,170 : rem 80
49250 DATA170,170,32,253,174,32,158 : rem 244
49257 DATA173,32,247,183,165,20,141 :rem 250
49264 DATA12,192,165,21,141,13,192 :rem 191
49271 DATA32,253,174,32,158,173,56 : rem 205
49278 DATA165,71,233,3,133,75,165 :rem 158
49285 DATA72, 233, 0,133, 76, 162,1 : rem 45
49292 DATA173, 12, 192,157, 20, 192, 173 : rem 252
49299 DATA13, 192, 157, 40, 192, 169,1 :rem 161
49306 DATA157,60,192,169,0,157,80 :rem 156
49313 DATA192,189,60,192,141,16,192 :rem 255
49320 DATA189,80, 192,141, 17, 192, 189 :rem 6
49327 DATA20,192,141,18,192,189,40 : rem 202
49334 DATA192,141,19,192,32,47,195 :rem 208
49341 DATA173,11,192,48,4,202,208 :rem 142
49348 DATA221,96,189,60,192,141,16 :rem 211
49355 DATA192,189,80,192,141,17,192 : rem 8
49362 DATA169, 1,141, 18, 192, 169,0 :rem 102
49369 DATA141,19,192,32,101,195,189 : rem 5
49376 DATA20,192,141,18,192,141,14 :rem 195
49383 DATA192,189,40,192,141,19,192 :rem 7
49390 DATA141,15,192,32,47,195,173 : rem 205
49397 DATA11,192,48,3,76,167,193 : rem 119
49404 DATA32,131,195,173,16,192,141 : rem 244
49411 DATA3, 192, 173, 17, 192, 141, 4 :rem 93
49418 DATA192,173,14,192,141,5,192 : rem 203
49425 DATA173,15,192,141,6,192,32 .-rem 148
49432 DATA132,194,32,180,194,173,11 : rem 245
49439 DATA192, 48, 218, 173, 16, 192,141 :rem 6
49446 DATA3, 192, 173, 17, 192, 141,4 :rem 101
49453 DATA192,173,18,192,141,16,192 : rem
49460 DATA173,19,192,141,17,192,169 : rem 4
49467 DATA1, 141, 18, 192, 169 ,0,141 : rem 98
49474 DATA19,192,32,101,195,173,16 : rem 204
49481 DATA192,141,18,192,173,17,192 :rem 2
49488 DATA141, 19, 192, 173,3,192,141 :rem 207
49495 DATA16,192,173,4,192,141,17 :rem 157
49502 DATA192, 32, 47,195, 173,11,192 :rem 202
49509 DATA16,35,173,14,192,141,3 :rem 97
49516 DATA192,173,15,192,141,4,192 : rem 202
49523 DATA173,18,192,141,5,192,173 : rem 203
49530 DATA19,192,141,6,192,32,132 : rem 144
49537 DATA194,32,180,194,173,11,192 :rem 1
198
Applications and Utilities: 5
49544
49551
49558
49565
49572
49579
49586
49593
49600
49607
49614
49621
49628
49635
49642
49649
49656
49663
49670
49677
49684
49691
49698
49705
49712
49719
49726
49733
49740
49747
49754
49761
49768
49775
49782
49789
49796
49803
49810
49817
49824
49831
49838
49845
49852
49859
49866
49873
49880
DATA48, 152, 32,47, 195, 173, 11 :rem 156
DATA192,16,18,173,16,192,141 : rem 202
DATA3, 192, 173, 17, 192, 141,4 :rem 105
DATA192,32,132,194,32,31, 195 :rem 204
DATA76,241,192,234,189,20,192 :rem 6
DATA141,3,192,189,40,192,141 :rem 209
DATA4, 192, 173, 16, 192, 141, 5 : rem 107
DATA192,173,17,192,141,6,192 :rem 211
DATA32,132,194,32,31,195,173 :rem 193
DATA16,192,141,18,192,141,3 : rem 147
DATA192,173,17,192,141,19,192 :rem 1
DATA141,4,192,32,81,195,189 : rem 157
DATA20,192,141,18,192,189,40 : rem 206
DATA192,141,19,192,32,101,195 : rem 251
DATA173,11,192,48,15,189,60 : rem 158
DATA192,141,18,192,189,80,192 :rem 15
DATA141,19,192,32,101,195,169 : rem 2
DATA1, 141, 18, 192, 169, 0,141 : rem 96
DATA19,192,173,3,192,141,16 : rem 153
DATA192,173,4,192,141,17,192 :rem 212
DATA173,11,192,16,52,189,60 : rem 160
DATA192,232,157,60,192,202,189 :rem 55
DATA80,192,232,157,80,192,32 :rem 215
DATA101,195,173,16,192,157,20 s rem 249
DATA192, 173, 17, 192, 157,40, 192 :rem 1
DATA32,131,195,32,131,195,202 : rem 246
DATA173,16,192,157,60,192,173 :rem 6
DATA17,192,157,80,192,76,128 : rem 217
DATA194,32,131,195,232,173,16 : rem 250
DATA192,157,60,192,173,17,192 :rem 11
DATA157,80,192,202,189,20,192 : rem 4
DATA232,157,20,192,202,189,40 : rem 249
DATA192, 232, 157,40, 192, 202, 32 :rem 253
DATA101,195,32,101,195,173,16 trem 251
DATA192,157,20,192,173,17,192 trem 6
DATA157,40,192,232,76,162,192 trem 13
DATA160,3,165,75,133,79,133 trem 165
DATA81, 165, 76, 133, 80, 133,82 trem 156
DATA24,165,79,109,3,192,133 trem 154
DATA79,165,80,109,4,192,133 trem 164
DATA80,24,165,81,109,5,192 trem 107
DATA133,81,165,82,109,6,192 trem 157
DATA133,82,136,208,223,96,160 trem 4
DATA0, 140, 11, 192, 177, 79, 141 trem 152
DATA7, 192, 177, 81, 141, 8, 192 trem 115
DATA200,152,205,7,192,240,2 trem 145
DATA176,13,205,8,192,240,21 trem 153
DATA144,19,238,11,192,76,30 trem 159
DATA195.205.8.192.240,2,176 trem 159
5: Applications and Utilities
49887 DATA62 , 206 ,11, 192, 76, 30, 195 : rem 163
49894 DATA140,9, 192, 160,1, 177,79 :rem 117
49901 DATA133, 77, 200, 177, 79, 133,78 :rem 213
49908 DATA172,9,192,136,177,77,141 :rem 220
49915 DATA10,192,140,9,192,160,1 s rem 93
49922 DATA177,81,133,77,200,177,81 :rem 211
49929 DATA133,78,172,9,192,177,77 :rem 181
49936 DATA200,205,10,192,208,3,76 :rem 145
49943 DATA195, 194, 144, 184, 76,224, 194 trem 69
49950 DATA96,160,2,177,79,72,177 : rem 124
49957 DATA81,145,79,104,145,81,136 :rem 217
49964 DATA16,243,96,169,0,141,11 :rem 105
49971 DATA192,173,17,192,205,19,192 trem 8
49978 DATA144,6,240,8,238,11,192 : rem 111
49985 DATA96,206,11,192,96,173,16 :rem 171
49992 DATA192,205,18,192,144,244,208 : rem 56
49999 DATA238,96,173,16,192,24,109 :rem 228
50006 DATA18, 192, 141, 16,192,173,17 :rem 190
50013 DATA192,109,19,192,141,17,192 :rem 241
50020 DATA96,169,0,141,11,192,56 : rem 87
50027 DATA173,16,192,237,18,192,141 : rem 245
50034 DATA16, 192, 173, 17,192,237, 19 :rem 198
50041 DATA192,141,17,192,176,3,206 : rem 187
50048 DATA11,192,96,238,16,192,208 :rem 202
50055 DATA3, 238, 17, 192, 96, 170, 170 : rem 148
50062 DATA170,170,170,170,170,170,170 trem 71
50069 DATA170,170,170,170,170,170,170 trem 78
50076 DATA170,170,170,170,170,170,170 trem 76
50083 DATA170,170,170,170,170,170,170 trem 74
50090 DATA170,170,170,170,170,170,170 trem 72
50097 DATA170,170,170,170,170,170,170 trem 79
50104 DATA170,170,170,170,170,170,170 trem 68
50111 DATA170,170,170,170,170,81,85 trem 232
50118 DATA73,67,75,83,79,82,84 trem 21
50125 DATA32,76,79,65,42,32,32 trem 252
50132 DATA3,255,50,48,44,82,69 trem 254
50139 DATA65,68,32,69,82,82,79 trem 21
50146 DATA82,44,49,56,44,48,48 trem 12
50153 DATA0, 170, 170, 170, 170, 81, 85 trem 134
50160 DATA73,67,75,83,79,82,84 trem 18
50167 DATA32,76,79,65,68,69,82 trem 25
50174 DATA16,255,256 trem 19
200
Applications and Utilities: 5
Program 2. Sort Test
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
100 PRINT" {CLR} " :rem 245
110 N=100 :rem 174
120 DIM AA$(N) :rem 178
130 PRINT" CREATING "N" RANDOM STRINGS" : rem 47
140 SD=-TI:A=RND(SD) : rem 183
150 FOR 1=1 TO N :rem 37
160 PRINT I "{UP}" :rem 66
170 N1=INT(RND(1)*10+1) : rem 221
180 A$="" :rem 127
190 FOR J=l TO Nl :rem 91
200 B$=CHR$(INT(RND(l)*26+65)) :rem 81
210 A$=A$+B$ :rem 43
220 NEXT J :rem 29
230 AA$(I)=A$ :rem 119
240 NEXT I :rem 30
250 PRINT "HIT ANY KEY TO START SORT" : rem 151
260 GET A$:IF A$="" THEN 260 : rem 83
270 PRINT "SORTING..." : rem 26
280 T1=TI :rem 249
290 SYS 49152, N,AA$(1) : rem 109
300 T2=TI :rem 243
310 PRINT "DONE" : rem 139
320 PRINT "HIT ANY KEY TO PRINT SORTED STRINGS"
:rem 71
330 GET A$:IF A$="" THEN 330 : rem 79
340 FOR 1=1 TO N: PRINT I , AA$ ( I ) :NEXT : rem 27
350 PRINT: PRINT N" ELEMENTS SORTED IN" (T2-T1 )/60"S
ECONDS" :rem 180
201
Dan Carmichael
64 Freeze
Freezing a BASIC program, It's happened. You're play-
stopping it in midframe, is a ing a fast-action arcade
handy feature, especially in game, and your hand
game programs. Players get is cramped from being
exhausted, want to answer the wra PP ed to ° tigMy nownd.
telephone, or make a sandwich, the joystick. Or your back
but don't want to give up that SpaSmS T"'
,. , «^7t* » i Or the phone rings and you
high score. 64 Freeze lets just hav e to answer it. But
you stop and restart programs youVe got the highest score
with single keypresses. evei . and if you get UP) the
game will continue. Unfortunately, the joystick can't run itself, and
you'll lose the game.
If you've placed "64 Freeze" in memory, however, you can stop
the program at any time by pressing one key. Nothing will be lost;
the program simply freezes. Anything on the screen still shows; it just
doesn't move. Hitting another key unfreezes the program, restarting
it. You can continue with the program from where you left off.
Freeze Keys
Type 64 Freeze in and SAVE it to tape or disk. "The Automatic Proof-
reader," Appendix C, will make it simple to enter the program
correctly the first time.
After loading and running the program, you'll see a display list.
You can customize 64 Freeze by selecting your own key combination
for freeze and unfreeze. If you want to use the default keys, just hit
RETURN twice. The f 1 key will then freeze the action, and the f 3 key
restarts the program. To choose your own keys, enter the appropriate
number before hitting RETURN.
The SYS command to access the routine also shows on the
screen. Whenever you want to use 64 Freeze, just enter SYS679 in
either direct mode or as a program line within your game. If you use
the last method, make sure that 64 Freeze has been loaded into
memory before you try to call it.
Once you've selected the two control keys, try the freeze func-
tion. Type NEW, then load and run a BASIC program. Let it run for
a bit, then hit the freeze key (f 1 if you chose the default setting). The
program immediately pauses. Press the unfreeze key (f3 if default
used) to restart the program. That's it.
202
n
Applications and Utilities: 5
n
n
n
n
n
Interrupting Danger
64 Freeze uses a machine language interrupt by calling the IRQ inter-
rupt vectors at $315-8314. Because of this, if your program also uses
interrupts, 64 Freeze may not work. Programs which use machine
language in other ways still should be able to access 64 Freeze; it's
only interrupts that interfere. Any completely BASIC program can call
this routine. We've used this program at COMPUTE! for several
months, freezing programs so that we can take photographs of the
monitor screen, and we've had difficulties with only a few. All of
them used machine language interrupts.
64 Freeze
For mistake-proof program entry, be sure to read ' The Automatic Proofreader, ' 'Appendix C.
lid FORA=679T0714:READB:POKEA,B:NEXT : rem 212
20 PRINT" {CLR}{WHT} {DOWN} {15 RIGHT}64 FREEZE"
:rera 186
31 PRINT"{YEL}{DOWN}KEY ASSIGNMENTS: " :PRINT" {CYN}
{D0WN}F1= 4{4 SPACES}F3= 5{4 SPACES}F5= 6
{3 SPACES }F7= 3 {6 SPACES}" : rem 188
32 PRINT" { DOWN }£ = 48 {3 SPACES }= = 53 {3 SPACES } <
{SPACE}= 47{3 SPACES} > = 44" : rem 245
33 PRINT" {DOWN} 4 = 57{3 SPACES } t = 54{3 SPACES}+ =
40 {3 SPACES}- = 43" : rem 241
34 PRINT"{DOWN}? = 55{3 SPACES }CRSR{ 5 SPACES}CRSR"
: rem 163
35 PRINT" {9 SPACES}UP = 7{3 SPACES}RIGHT = 2"
: rem 63
36 PRINT" {DOWN} ENTER THE KEY YOU WISH TO FREEZE TH
E C64": PRINT "{UP} WITH (SEE TABLE)" : rem 43
40 INPUT"{3 RIGHT}4{3 LEFT } " ;K1 :P0KE715 ,K1 : rem 255
45 PRINT" { DOWN }ENTER THE KEY YOU WISH TO UNFREEZE
{ SPACE }THE": PRINT "C64 WITH (SEE TABLE)" : rem 61
50 INPUT" {3 RIGHT} 5{ 3 LEFT } " ?K2 :POKE716 ,K2 :rem 4
60 PRINT" {DOWN} TO START PR0GRAM{2 SPACES}* SYS679
* g 7 3 " :rem 36
100 DATA120,169,180,141, 20, 3, 169, 2 :rem 168
110 DATA141,21,3,88, 96, 165, 197, 205 :rem 191
120 DATA203, 2, 240, 3, 76, 49, 234, 32 : rem 73
130 DATA159,255,165,197,205,204, 2, 240 :rem 79
140 DATA243,76,190,2,234, 234, 234, 234 :rem 25
203
Harold D. Vanderpool
64 Merge
DATA statements, subroutines, Up to now, if you wanted
and even entire files can be to put two BASIC programs
merged with other programs together, or add DATA state-
using this machine language ments created by a sound,
utility. Not only will it save you s P rite - or character editor to
time, since you won't have to your own program, you had
retype the lines merged, but it to r f? e ^rything^ It
^ ^ , ' was twice the work. Many
allows you to write longpro- programmers useamo duL
grams in pieces, or modules, approach to program design,
and then later link them together. an( j \^ to use me same
"64 Merge" is for disk merges, subroutine over and over in
although an explanation of different programs. Why
how to process tape merges retype that joystick routine
is included. when it 's already on a disk?
"64 "Merge" lets you
avoid all that time at the keyboard. It splices programs together as if
you'd typed them in. New lines are placed in the proper order, and
if a new line number matches an old line number, the latter is replaced.
To use this program, you need a disk drive. There is a way to
merge programs using tape, which is also explained in this article,
but the method is more cumbersome. You can't use the 64 Merge
program with tape.
Type in and save 64 Merge. Use Appendix C, "The Automatic
Proofreader," to make sure it's entered correctly. As you type in the
DATA statements in lines 200-240, you'll notice that there are strange-
looking number and letter combinations. You probably haven't
typed in a listing like this before. The two-character combinations
do mean something; they are values converted into hexadecimal
notation. You don't have to know how to convert from decimal to
hexadecimal, or even anything about machine language, to enter
this program. Simply type it in exactly as it appears. As soon as you've
done that, you're ready to begin merging programs.
ASCII Files
In order to put together two programs using 64 Merge, you first have
to make an ASCII file of one of them. It's probably easier if you
choose the shorter program for this.
Load the program or routine you wish to merge and then type
this line in direct mode (without a line number):
OPEN 2,8,3, "/*fen«me,SEQ,W":CMD2:LIST[nl-n2]
204
Applications and Utilities: 5
(The nl-n2 range in brackets after the LIST command is optional. If
you want, you can include a number range here, and only that por-
tion of the program will be merged. Make sure you do include the
command LIST, however, even if you don't specify a range. Omitting
the range option means the entire program will be merged later.)
As soon as you press RETURN, an ASCII file is created on the
disk in the drive under the filename you specified. You can put the
ASCII file on any disk that has room. The cursor will return to the
screen, and you should type:
PRINT#2:CLOSE2
Press RETURN, and the red indicator light on the drive will go off.
The file is now CLOSEd, and it's ready to use in the merge operation.
Prompted SYSing
Type NEW, then load and run 64 Merge. The program is completely
relocatable. In other words, it can be placed anywhere in memory,
as long as there's room. By default it occupies part of the cassette
buffer, an area you don't normally use when you have a disk drive.
Other suitable locations are in the range from 49152 to 53247. If you
don't want it placed in the cassette buffer, the next best place would
be at 49152.
The first prompt you'll see when the program has been run is the
starting address of the routine. If you want to relocate it, enter the
appropriate memory location and press RETURN. Hitting the RETURN
key without typing anything in simply tells the program to use the
default area, the cassette buffer.
At the next prompt, enter the filename you used earlier when
you created your ASCII file. Hitting the RETURN key then runs 64
Merge. The machine language data is POKEd into memory, and several
SYS commands are displayed on the screen. You'll be using these
SYSs in a moment. If you relocate the program to another area of
memory, you should jot these SYS addresses down, for they'll vary
from what shows below. Relocating the program to different areas
will display different locations to SYS. It's simpler if you just leave
the program in the cassette buffer.
Merging
Load the program you want merged to (not the one you created the
ASCII file from). Make sure the disk with the ASCII file is in the disk
drive and then type:
SYS 882
SYS 904
205
5: Applications and Utilities
hitting RETURN after each. (Remember that if you relocated the
program, all the SYSs will be different from what shows here.)
Press the SHIFT and CLR/HOME keys together. As soon as the
screen clears, type:
SYS 828
to actually merge the two programs. The drive will make some
noise and the red light will remain on until you CLOSE the operation
by entering:
SYS 882:SYS 910
What was once two BASIC programs is now one. LIST it to check.
"You've successfully completed a disk merge. You can run or modify
the merged program, or save it normally under a new filename.
Tape Merge
The method used to merge two programs using the disk drive was
first explored by Raeto West in his book Programming the PET/CBM.
My program is a Commodore 64 version of that process. Merging
programs on tape, however, was best described by Jim Butterfield in
"BASIC Program Merges: PET and VIC," which appeared in the June
1982 issue of COMPUTE! magazine. If you don't have a copy of that
issue, here's a review of the process.
Create an ASCII version of the program to be merged by loading
it into memory, making sure a blank tape is in the Datassette, and
typing the following in direct mode:
OPEN2 ,\,V, 1 filename" :LIST[nl-n2]
The LIST command is necessary, but the number range is optional.
You can specify a range of lines if you want to merge only part of a
program, such as a subroutine, into another program.
Press the RETURN key and obey the PRESS RECORD & PLAY
ON TAPE prompt. The tape drive will start and stop, eventually stop-
ping completely. Again in direct mode, enter:
PRINT#2:CLOSE2
When you press RETURN, the tape will move again for a bit, then
stop. The screen should show the READY message. You've just
created an ASCII file on tape. Set this tape aside.
Load the program to be merged to, place the tape with the ASCII
file back in the Datassette, and type:
POKE19,l:OPEN2
206
Applications and Utilities: 5
Press RETURN, then the tape PLAY button. The tape will move, even-
tually displaying the ASCII filename you earlier specified. Do not
release the PLAY button on the tape player. The next few key entries
must be followed exactly. Press the SHIFT and CLR/HOME keys
together, wait for the screen to clear, and then press the cursor down
key three times. You'll see the cursor blinking on line four. In direct
mode, enter:
PRINT" { home } ":POKE198,l:POKE631,13:POKE153,l
After the tape has moved and stopped a few times, you see either the
PSYNTAX ERROR or POUT OF DATA message on the screen. Ignore
it; it's not a real error. Close the file by typing:
CLOSE2
When RETURN is pressed, the two programs have been merged. You
can save, run, or modify the merged version.
That's all there is to it. By using this utility, you'll find it easy to
splice two BASIC programs together. You'll never have to retype your
favorite subroutines or DATA statements again.
64 Merge
For mistake-proof program entry, be sure to read ' 'The Automatic Proofreader, "Appendix C.
5 PRINT" {CLR} {DOWN} "TAB(10) "COMMODORE 64 MERGE
{DOWN}" :rem 7
10 I NPUT " START ADDRESS"; AD : rem 137
20 IFAD<820THENAD=828 : REM DEFAULTS TO CASSETTE BUF
FER : rem 14
30 INPUT" {DOWN} FILENAME" ; N$ :L=LEN(N$ ) : IFN$=" "THEN3
:rem 233
40 PRINT" {DOWNjWAIT ONE MINUTE 1" : rem 80
50 FORI=0TO89 :READA$ :A=ASC ( A$ ) -48 : 1 FA> 9THENA=A-7
: rem 130
60 B=ASC(RIGHT$(A$,l))-48:IFB>9THENB=B-7 : rem 49
70 N=A*16+B:POKEAD+I,N:NEXT:BI=I+AD : rem 129
80 F0RI=1T0L : POKEBI+I-1 , ASC (MID$ ( N$ , I , 1 ) ) :NEXT : BI=
I+BI :rem 28
90 FORI=0TO5:READC: POKEBI+I-1, C:NEXT : rem 37
100 POKEAD+55 ,L+6 :AA=AD+88 :Al%=AA/256 :A2=AA-A1%*25
6 :rem 31
110 POKEAD+57,A2:POKEAD+59,Al% : rem 198
120 PRINT"{DOWN}OPEN":PRINT"{2 SPACES} SYS "AD+54: PR
INT" {2 SPACES} SYS "AD+76 : rem 241
130 PRINT"{DOWN}MERGE":PRINT"{2 SPACESjPRESS [CLEA
R]": PRINT" {2 SPACES } SYS "AD : rem 44
140 PRINT"{DOWN}CLOSE":PRINT"{2 SPACES } SYS "AD+54 " :
SYS"AD+82 :rem 167
207
5: Applications and Utilities
200 DATA A9,08,20,B4,FF,A9,03,20,96,FF,A2,00,20,A5
,FF,C9,0A,F0,F9,C9,0D,F0,0A : rem 228
210 DATA 9D,00,02,E8, E0, 51 , F0 , 14, D0, EB, 8D, 77 , 02 , 20
,CA,AA,A9,13,20,D2,FF,A9,01 :rem 179
220 DATA 85,C6,4C,86,A4,4C,48,B2,A9,20,A2,20,A0,20
,20,BD,FF,A9,02,A2,08,A0,03 :rem 144
230 DATA 20,BA,FF,20,C0,FF,60 / A2,02,20,C6,FF,60,A9
,02,20, C3,FF, 60,30, 3A : rem 118
240 DATA 44,83,44,81,20,20,20 : rem 130
208
Richard Mansfield
RAMtest
How can you test your Don't let anyone tell you
computer's RAM chips to make that there's something
sure they're working? For all you impossibly complex about
know, they may be unreliable. machine language. It can be
This short machine language harder to *J°8 Oocate and
program tests every RAM ^ errors) _t^an^SIC^
memoty cell from location 2048 d - f ficuluolea^nortoTr^e.
to address 40960, and tells you You just need to mem .
if each is working properly. ori2e some new cornmands .
obtain and practice with some new tools (assemblers, disassemblers,
monitors); and pick up a few new programming techniques. Dis-
covering this for yourself, that machine language can be an easy —
and fascinating — way to communicate with your computer, may
spur you on to write your own ML programs.
"RAMtest," the program below, is an example of one of the most
common ways that machine language routines are printed in books
and magazines. This kind of program is called a BASIC loader. The
value of loaders is that the user need not understand anything about
the machine language program. It's the easy way to use machine lan-
guage. Just type in the BASIC program as it appears, type RUN, and
the machine language (the numbers in the DATA statements) is POKEd
into memory for you.
Strange Strings
RAMtest is a useful program: It tests your Random Access Memory
(RAM) to be sure that every cell is operating correctly. RAM chips are
generally quite reliable, but you might have one fail on you. There are
various odd things that can happen during a program RUN as the
result of a faulty RAM chip. One sign would be the sudden appearance
of strange strings. For example, you might type AS? = ' ABCDEFG"
and when you asked to see A$ (by typing ?A$), you would get
ABQEFG or something.
Here's how to use RAMtest:
1. Type it in.
2. Type SAVE (to keep a copy on tape or disk).
3 . Type RUN. The DATA will be loaded into a safe area of your
computer which is not part of BASIC RAM. We're loading the machine
language program into decimal address 828-1019. This is the cassette
buffer RAM, and it 's unused by BASIC except during Datassette opera-
tions. We can't store the machine language program in normal
209
5 : Applications and Utilities
BASIC RAM because we're going to fill each memory cell with all 256
possible numbers as our test. That would cause the program to test
— and thereby obliterate — itself. The cassette buffer is a popular, safe
place to put machine language since it is out of BASIC'S way.
4. After you see READY on the screen, your machine language
is sitting down in lower RAM memory (decimal 864-995), waiting
for you to activate it. You send control of the computer to a machine
language program by using BASIC'S SYS command. However, machine
language programs do not necessarily start with the first number in
their sequence. The entry point could be anywhere within the rou-
tine. Unlike BASIC, which always begins with the lowest line num-
ber, machine language might store text messages or other information
below the entry point. That's the case in the RAMtest program. To
start it going, type SYS 884.
A Vibrating Square
If all your DATA numbers were correctly typed in, you should now
see two things happening onscreen. Up in the left corner you'll
see a vibrating square. This is a visual demonstration of what's hap-
pening to each of your RAM memory cells in turn. As each number
from to 255 is POKEd into each cell of the computer, it's also
being POKEd into the first screen memory cell so you can see it
happening. (Machine language POKEs are called STA, meaning STore
the Accumulator.)
The other thing you'll notice is that the decimal address range
currently being tested appears onscreen. This program tests cells
from 2048 up to address 40960. At the conclusion, the words TEST
OVER will signify that every memory cell tested has correctly stored
every possible number.
Now, type LIST. You can see the effect of our mass POKEs. For
a line number you get 65 5 3 5 . (However, for technical reasons, you
can't actually use line numbers larger than 63999 in BASIC.) Line
numbers are always stored in two-byte units, and this is the biggest
number that the computer can hold within two memory bytes. Fol-
lowing that are more than 200 pi symbols. This is the symbol you
get by typing ?CHR$(255). We're not seeing screen RAM memory
when we ask for a LIST. Instead, we see a translation of a BASIC pro-
gram. The series of 255's appears, after this translation, as pi symbols.
It means that each of these cells — you're looking at the bottom of
BASIC RAM where BASIC programs start — is now holding a number
255 after having held everything from up to 255 during the test.
210
Applications and Utilities: 5
If you want to regain control and return to normal BASIC con-
ditions after this test, you'll need to POKE 2048,0. The very first
cell in BASIC RAM must contain a zero for things to work correctly.
Most likely, your RAM memory passed the test. Just to see what
would happen if there were a bad cell, we can make the test try to
POKE into Read Only Memory (ROM). It will try, but ROM is pro-
tected against being written over, so the attempted POKE will fail and
it will appear to the RAMtest program that there is a bad cell. To try
this, LOAD RAMtest from your disk or tape. Then RUN. Then type
POKE 885,245. This will set the testing to start at memory cell
62720, and you'll see the results when you start the test with SYS 884 .
Tortoise and Hare
You could write a program in BASIC to perform this same test, but
you'd need to start the test higher up in memory and you'd need to
leave it RUNning overnight. The great speed of machine language
execution makes it ideal for large tasks like RAM testing. Machine
language does have advantages, even if it may seem more difficult
to write.
RAMtest
Formtstake-pmofpmgramentry,besutvtotvad'ybeAutotnattcPmoftvader"AppendixC.
800
FOR AD RES
=864
TO 995: RE AD DATTA: POKE
ADRES, DAT
TA : NEXT ADRES
:rem 53
864
DATA
84,
69,
83, 84, 32, 79
:rem 31
870
DATA
86,
69,
82, 32, 32, 66
: rem 18
876
DATA
65,
68,
32, 66, 89, 84
:rem 34
882
DATA
69,
32,
169, 8, 133, 58
: rem 72
888
DATA
169,
0,
133, 57, 160,
: rem 56
894
DATA
24,
141,
0, 4, 145, 57
:rem 1
900
DATA
209,
57,
240, 21, 152, 72
: rem 144
906
DATA
165,
58,
72, 32, 179, 3
: rem 64
912
DATA
104,
133
, 58, 104, 168, 169
: rem 255
918
DATA
0, 230,
57, 208, 7, 230
zrem 47
924
DATA
58,
24,
105, 1, 208, 221
:rem 94
930
DATA
200,
208
, 218, 32, 193, 3
:rem 142
936
DATA
230,
58,
165, 58, 201, 160
: rem 205
942
DATA
144,
207
, 76, 208, 3, 162
: rem 154
948
DATA
10,
160,
0, 185, 106, 3
:rem 43
954
DATA
32,
210,
255, 200, 202, 208
:rem 236
960
DATA
246,
72,
152, 72, 169, 32
: rem 160
966
DATA
32,
210,
255, 32, 201, 189
:rem 201
972
DATA
104,
168
, 104, 96, 169, 13
:rem 212
978
DATA
32,
210,
255, 160, 0, 185
: rem 151
984
DATA
96,
3, 32, 210, 255, 200
:rem 99
990
DATA
192,
10,
208, 245, 96,
: rem 105
211
□
□
□
□
□
D
□
■ Appendices
□
□
□
□
□
D
□
Appendix: A
A Beginner's Guide to
Typing In Programs
What Is a Program?
A computer cannot perform any task by itself. Like a car without gas,
a computer has potential, but without a program, it isn't going any-
where. Most of the programs published in this book are written in a
computer language called BASIC. BASIC is easy to learn and is built
into all Commodore 64s.
BASIC Programs
Computers can be picky. Unlike the English language, which is full
of ambiguities, BASIC usually has only one right way of stating some-
thing. Every letter, character, or number is significant. A common
mistake is substituting a letter such as O for the numeral 0, a lower-
case 1 for the numeral 1, or an uppercase B for the numeral 8. Also,
you must enter all punctuation such as colons and commas just as
they appear in the book. Spacing can be important. To be safe, type
in the listings exactly as they appear.
Braces and Special Characters
The exception to this typing rule is when you see the braces, such as
{ DOWN } . Anything within a set of braces is a special character or
characters that cannot easily be listed on a printer. When you come
across such a special statement, refer to Appendix B, "How to Type
In Programs."
About DATA Statements
Some programs contain a section or sections of DATA statements.
These lines provide information needed by the program. Some DATA
statements contain actual programs (called machine language); others
contain graphics codes. These lines are especially sensitive to errors
If a single number in any one DATA statement is mistyped, your
machine could lock up, or crash. The keyboard and STOP key may
seem dead, and the screen may go blank. Don't panic — no damage
is done. To regain control, you have to turn off your computer,
then turn it back on. This will erase whatever program was in
memory, so always save a copy of your program before you run
it. If your computer crashes, you can load the program and look
for your mistake.
215
A: Appendix
Sometimes a mistyped DATA statement will cause an error mes-
sage when the program is run. The error message may refer to the
program line that reads the data. The error is still in the DATA
statements, though.
Get to Know Your Machine
You should familiarize yourself with your computer before attempt-
ing to type in a program. Learn the statements you use to store and
retrieve programs from tape or disk. You'll want to save a copy of
your program, so that you won't have to type it in every time you
want to use it. Learn to use your machine's editing functions. How
do you change a line if you made a mistake? You can always retype
the line, but you at least need to know how to backspace. Do you
know how to enter reverse video, lowercase, and control characters?
It's all explained in your computer's manuals.
A Quick Review
1 . Type in the program a line at a time, in order. Press RETURN at the
end of each line. Use the DELete key to correct mistakes.
2 . Check the line you've typed against the line in the book. You can
check the entire program again if you get an error when you run
the program.
216
Appendix: B
How to Type In Programs
To make it easy to know exactly what to type when entering one
of these programs into your computer, we have established the
following listing conventions.
Generally, Commodore 64 program listings will contain words
within braces which spell out any special characters: {DOWN}
would mean to press the cursor down key. { 5 SPACES } would mean
to press the space bar five times.
To indicate that a key should be shifted (hold down the SHIFT
key while pressing the other key), the key would be underlined in
our listings. For example, S would mean to type the S key while hold-
ing the SHIFT key. This would appear on your screen as a heart
symbol. If you find an underlined key enclosed in braces (eg.,
{ 10 N}), you should type the key as many times as indicated (in
our example, you would enter ten shifted N's).
If a key is enclosed in special brackets [< >], you should hold
down the Commodore key while pressing the key inside the special
brackets. (The Commodore key is the key in the lower-left corner of
the keyboard.) Again, if the key is preceded by a number, you should
press the key as many times as necessary.
Rarely, you'll see a solitary letter of the alphabet enclosed in
braces. These characters can be entered by holding down the CTRL
key while typing the letter in the braces. For example, {A} would
indicate that you should press CTRL-A.
About the quote mode: You know that you can move the cursor
around the screen with the CRSR keys. Sometimes a programmer
will want to move the cursor under program control. That's why you
see all the { LEFT } 's, { HOME } 's, and { BLU } 's in our programs. The
only way the computer can tell the difference between direct and
programmed cursor control is the quote mode.
Once you press the quote (the double quote, SHIFT-2), you are
in the quote mode. If you type something and then try to change it
by moving the cursor left, you'll only get a bunch of reverse video
lines. These are the symbols for cursor left. The only editing key
that isn't programmable is the DEL key; you can still use DEL to back
up and edit the line. Once you type another quote, you are out of
quote mode.
217
B: Appendix
You also go into quote mode when you INSeiT spaces into a line.
In any case, the easiest way to get out of quote mode is to just press
RETURN. You'll then be out of quote mode and you can cursor up
to the mistyped line and fix it.
Use the following table when entering cursor and color
control keys:
When You
Read:
{CLR}
{HOME}
{UP}
{DOWN}
{LEFT}
{RIGHT}
{RVS}
{OFF}
{BLK}
{WHT}
{RED}
{CYN}
{FUR}
{GRN}
{BLU}
{YEL}
Press:
SHIFT
CLR/HOME
CLR/HOME
SHIFT
f CRSR |
f CRSR |
SHIFT
«— CRSR-*
— CRSR-»
CTRL
9
CTRL
CTRL
1
CTRL
2
CTRL
3
CTRL
4
CTRL
CTRL
CTRL
See:
m
CTRL
When You
Read:
§13
§23
§33
§43
§53
§63
§73
§83
{ Fl }
{ F2 }
{ F3 }
{ F4 }
{ F5 }
{ F6 }
{ F7 }
{ F8 }
Press:
See:
COMMODORE
LU
COMMODORE | |T]
COMMODORE
LU
COMMODORE
S
COMMODORE
m
COMMODORE | [7]
COMMODORE (~T|
COMMODORE
fl
SHIFT
fl
a
SHIFT
13
SHIFT
SHIFT
218
Appendix: C
Charles Brannon
The Automatic Proofreader
"The Automatic Proofreader" will help you type in program listings
without typing mistakes. It is a short error-checking program that
hides itself in memory. When activated, it lets you know immediately
after typing a line from a program listing if you've made a mistake.
Please read these instructions carefully before typing any programs
in this book.
Preparing the Proofreader
1. Using the listing below, type in the Proofreader. Be very care-
ful when entering the DATA statements — don't type an 1 instead
of a 1, an O instead of a 0, extra commas, etc.
2. Save the Proofreader on tape or disk at least twice before
running it for the first time. This is very important because the
Proofreader erases part of itself when you first type RUN.
3. After the Proofreader is saved, type RUN. It will check itself
for typing errors in the DATA statements and warn you if there's
a mistake. Correct any errors and save the corrected version. Keep
a copy in a safe place — you'll need it again and again, every time
you enter a program from this book, COMPUTEl's Gazette, or
COMPUTE! magazine.
4 . When a correct version of the Proofreader is run, it activates
itself. You are now ready to enter a program listing. If you press
RUN/STOP-RESTORE, the Proofreader is disabled. To reactivate it,
just type the command SYS 886 and press RETURN.
Using the Proofreader
All listings in this book have a checksum number appended to the
end of each line, for example, :rem 123. Don't enter this statement
when typing in a program. It is just for your information. The rem
makes the number harmless if someone does type it in. It will, how-
ever, use up memory if you enter it, and it will confuse the Proof-
reader, even if you entered the rest of the line correctly.
When you type in a line from a program listing and press
RETURN, the Proofreader displays a number at the top of your screen.
This checksum number must match the checksum number in the
printed listing. If it doesn't, it means you typed the line differently
than the way it is listed. Immediately recheck your typing. Remem-
ber, don't type the rem statement with the checksum number; it is
219
C: Appendix
published only so you can check it against the number which
appears on your screen.
The Proofreader is not picky with spaces. It will not notice
extra spaces or missing ones. This is for your convenience, since
spacing is generally not important. But occasionally proper spacing
is important, so be extra careful with spaces, since the Proofreader
will catch practically everything else that can go wrong.
There's another thing to watch out for: If you enter the line by
using abbreviations for commands, the checksum will not match up.
But there is a way to make the Proofreader check it. After entering
the line, LIST it. This eliminates the abbreviations. Then move the
cursor up to the line and press RETURN. It should now match the
checksum. You can check whole groups of lines this way.
Special Tape SAVE Instructions
When you're done typing a listing, you must disable the Proofreader
before saving the program on tape. Disable the Proofreader by press-
ing RUN/STOP-RESTORE (hold down the RUN/STOP key and sharply
hit the RESTORE key). This procedure is not necessary for disk, but
you must disable the Proofreader this way before a tape SAVE.
SAVE to tape erases the Proofreader from memory, so you'll have
to load and run it again if you want to type another listing. SAVE to
disk does not erase the Proofreader.
Hidden Perils
The Proofreader's home in the 64 is not a very safe haven. Since the
cassette buffer is wiped out during tape operations, you need to
disable the Proofreader with RUN/STOP-RESTORE before you save
your program. This applies only to tape use. Disk users have nothing
to worry about.
Not so for 64 owners with tape drives. What if you type in a
program in several sittings? The next day, you come to your com-
puter, load and run the Proofreader, then try to load the partially com-
pleted program so you can add to it. But since the Proofreader is
trying to hide in the cassette buffer, it is wiped out!
What you need is a way to load the Proofreader after you've
loaded the partial program. The problem is, a tape load to the buffer
destroys what it's supposed to load.
After you've typed in and run the Proofreader, enter the follow-
ing lines in direct mode (without line numbers) exactly as shown:
A$ = "PROOFREADER.T": B$ = "{ 10 SPACES }": FOR X = 1 TO 4:
A$=A$+B$:NEXTX
220
Appendix: C
FOR X = 886 TO 1018: A$ = A$ + CHR$ (PEEK(X)): NEXTX
OPEN l,l,l,A$:CLOSEl
After you enter the last line, you will be asked to press record
and play on your cassette recorder. Put this program at the beginning
of a new tape. This gives you a new way to load the Proofreader.
Anytime you want to bring the Proofreader into memory without
disturbing anything else, put the cassette in the tape drive, rewind,
and enter:
OPENl:CLOSEl
You can now start the Proofreader by typing SYS 886. To test
this, PRINT PEEK (886) should return the number 173- If it does
not, repeat the steps above, making sure that A$ ("PROOFREADER.T")
contains 13 characters and that B$ contains 10 spaces.
You can now reload the Proofreader into memory whenever
LOAD or SAVE destroys it, restoring your personal typing helper.
Replace Original Proofreader
If you typed in the original version of the Proofreader from the
October 1983 issue of COMPUTEl's Gazette, you should replace it
with the improved version below.
Automatic Proofreader
100 PRINT" {CLR}PLEASE WAIT ..." :FORI=886TO1018 : READ
A : CK=CK+A : POKEI , A : NEXT
110 IF CK017539 THEN PRINT" {DOWN} YOU MADE AN ERRO
R": PRINT "IN DATA STATEMENTS .": END
120 SYS886:PRINT"{CLR}{2 DOWN} PROOFREADER ACTIVATE
D. " :NEW
886 DATA 173,036,003,201,150,208
892 DATA 001,096,141,151,003,173
898 DATA 037,003,141,152,003,169
904 DATA 150,141,036,003,169,003
910 DATA 141,037,003,169,000,133
916 DATA 254,096,032,087,241,133
922 DATA 251,134,252,132,253,008
928 DATA 201,013,240,017,201,032
934 DATA 240,005,024,101,254,133
940 DATA 254,165,251,166,252,164
946 DATA 253,040,096,169,013,032
952 DATA 210,255,165,214,141,251
958 DATA 003,206,251,003,169,000
964 DATA 133,216,169,019,032,210
970 DATA 255,169,018,032,210,255
976 DATA 169,058,032,210,255,166
221
C: Appendix
982 DATA 254,169,000,133,254,172
988 DATA 151,003,192,087,208,006
994 DATA 032,205,189,076,235,003
1000 DATA 032,205,221,169,032,032
1006 DATA 210,255,032,210,255,173
1012 DATA 251,003,133,214,076,173
1018 DATA 003
222
Appendix: D
Charles Brannon
Using the Machine
Language Editor: MLX
Remember the last time you typed in the BASIC loader for a long
machine language program? "You typed in hundreds of numbers and
commas. Even then, you couldn't be sure if you typed it in right. So
you went back, proofread, tried to run the program, crashed, went
back and proofread again, corrected a few typing errors, ran again,
crashed again, rechecked your typing .... Frustrating, wasn't it?
Until now, though, that has been the best way to get machine
language into your computer. Unless you happen to have an assem-
bler and are willing to tangle with machine language on the assembly
level, it is much easier to enter a BASIC program that reads DAIA
statements and POKEs the numbers into memory.
Some of these "BASIC loaders" use a checksum to see if you've
typed the numbers correctly. The simplest checksum is just the sum
of all the numbers in the DATA statements. If you make an error, your
checksum does not match up with the total. Some programmers
make your task easier by including checksums every few lines, so you
can locate your errors more easily.
Now, MLX comes to the rescue. MLX is a great way to enter all
those long machine language programs with a minimum of fuss.
MLX lets you enter the numbers from a special list that looks similar
to DATA statements. It checks your typing on a line-by-line basis. It
won't let you enter illegal characters when you should be typing
numbers. It won't let you enter numbers greater than 255 (forbidden
in ML). It will prevent you from entering the numbers on the wrong
line. In short, MLX makes proofreading obsolete.
Tape or Disk Copies
In addition, MLX generates a ready-to-use copy of your machine
language program on tape or disk. You can then use the LOAD com-
mand to read the program into the computer, as with any other
program. Specifically, you enter:
LOAD "program name",l,l(for tape)
or
LOAD "program name",8,l(for disk)
To start the program, you need to enter a SYS command that
transfers control from BASIC to your machine language program.
223
D: Appendix
The starting SYS is always listed in the article which presents the
machine language program in MLX format.
Using MLX
Type in and save MLX (you'll want to use it in the future). When you're
ready to type in the machine language program* run MLX. MLX asks
you for two numbers: the starting address and the ending address.
These numbers are given in the article accompanying the ML pro-
gram you're typing. For example, the addresses for "BASIC Aid"
should be 49152 and 52997 respectively.
You'll see a prompt. The prompt is the current line you are enter-
ing from the MLX-format listing. It increases by six each time you
enter a line. That's because each line has seven numbers — six actual
data numbers plus a checksum number. The checksum verifies that
you typed the previous six numbers correctly. If you enter any of the
six numbers wrong, or enter the checksum wrong, the 64 sounds a
buzzer and prompts you to reenter the line. If you enter the line
correctly, a bell tone sounds and you continue to the next line.
A Special Editor
You are not using the normal 64 BASIC editor with MLX. For example,
it will accept only numbers as input. If you make a typing error,
press the INST/DEL key; the entire number is deleted. You can press
it as many times as necessary, back to the start of the line. If you
enter three-digit numbers as listed, the computer automatically prints
the comma and goes on to accept the next number. If you enter less
than three digits, you can press either the space bar or the RETURN
key to advance to the next number. The checksum automatically
appears in reverse video for emphasis.
To make it even easier to enter these numbers, MLX redefines
part of the keyboard as a numeric keypad (lines 581-584).
When testing it, I've found MLX to be an extremely easy way to
enter long listings. With the audio cues provided, you don't even
have to look at the screen if you're a touch-typist.
Done at Last!
When you get through typing, assuming you type your machine
language program all in one session, you can then save the completed
U I o
H J K L
M , .
7 8 9
becomes 4 5 6
12 3
224
Appendix: D
and bug-free program to tape or disk. Follow the instructions dis-
played on the screen. If you get any error messages while saving, you
probably have a bad disk, or the disk is full, or you made a typo
when entering the MLX program. (Sorry, MLX can't check itself!)
Command Control
You don't have to enter the whole ML program in one sitting. MLX
lets you enter as much as you want, save it, and then reload the file
from tape or disk later. MLX recognizes these commands:
SHIFT-S:Save
SHIFT-L:Load
SHIFT-N:New Address
SHIFT-D:Display
Hold down SHIFT while you press the appropriate key. MLX
jumps out of the line you've been typing, so I recommend you do
it at a prompt. Use the Save command to store what you've been
working on. It will save on tape or disk as if you've finished, but
the tape or disk won't work, of course, until you finish typing.
Remember what address you stopped on. The next time you run
MLX, answer all the prompts as you did before, then insert the disk
or tape containing the stored file. When you get the entry prompt,
press SHIFT-L to reload the partly completed file into memory. Then
use the New Address command (SHIFT-N) to resume typing.
New Address and Display
After you press SHIFT-N, enter the address where you previously
stopped. The prompt will change, and you can then continue typing.
Always enter a New Address that matches up with one of the line
numbers in the special listing, or else the checksums won't match up.
You can use the Display command to display a section of your typing.
After you press SHIFT-D, enter two addresses within the line number
range of the listing. You can abort the listing by pressing any key.
Tricky Stuff
The special commands may seem a little confusing, but as you work
with MLX, they will become valuable. For example, what if you for-
got where you stopped typing? Use the Display command to scan
memory from the beginning to the end of the program. When you
reach the end of your typing, the lines will contain a random pattern
of numbers, quite different from what should be there. When you
see the end of your typing, press any key to stop the listing. Use the
New Address command to continue typing from the proper location.
225
D: Appendix
You can use the Save and Load commands to make copies of the
complete machine language program. Use the Load command to
reload the tape or disk, then insert a new tape or disk and use the Save
command to create a new copy. When resaving on disk it is best to
use a different filename each time you save. For example, I like to
number my work and use filenames such as AID1, AID2, AID3,
and so on.
One quirk about tapes made with the MLX Save command:
When you load them, the message "FOUND program" may appear
twice. The tape will load just fine, however.
I think you'll find MLX to be a true labor-saving program. Since
it has been tested by entering actual programs, you can count on it as
an aid for generating bug-free machine language. Be sure to save
MLX; it will be used for future applications in COMPUTE! Books,
COMPUTE! magazine, and COMPUTEl's Gazette.
MLX
For mistake-proof program entry 1 , be sure to read "The Automatic Proofreader," Appendix C.
10 REM LINES CHANGED FROM MLX VERSION 2.00 ARE 750
,765,770 AND 860 :rem 50
100 PRINT " { CLR } § 6 3 " ;CHR$(142) ;CHR$(8) ; :POKE53281,l
:POKE53280,1 :rem 67
101 POKE 788,52:REM DISABLE RUN/STOP : rem 119
110 PRINT" { RVS } { 39 SPACES}"; : rem 176
120 PRINT "{RVS} {14 SPACES } {RIGHT } {OFF } g* 5|£{ RVS }
{RIGHT} {RIGHT} {2 SPACES } g*§ { OFF } g* 3£jRVS }£
{RVS} {14 SPACES}"; :rem 250
130 PRINT" {RVS} {14 SPACES } {RIGHT } gG| {RIGHT}
{2 RIGHT} {0FF}£{RVS}£|*3{0FF}g*3{RVS}
{14 SPACES}"; :rem 35
140 PRINT "{RVS} {41 SPACES}" : rem 120
200 PRINT" {2 DOWN} { PUR} {BLK} MACHINE LANGUAGE EDIT
OR VERSION 2. 01 {5 DOWN}" : rem 237
210 PRINT"g53{2 UP} STARTING ADDRESS?{8 SPACES}
{9 LEFT}"; : rem 143
215 INPUTS:F=1-F:C$=CHR$(31+119*F) : rem 166
220 IFS< 2560R( S> 40960ANDS<49152 ) ORS> 53247THENG0SUB
3000:GOTO210 : rem 235
225 PRINT: PRINT: PRINT : rem 180
230 PRINT "g 53 {2 UP} ENDING ADDRESS? {8 SPACES }
{9 LEFT}"; : INPUTE :F=1-F:C$=CHR$ ( 31+119*F )
: rem 20
240 IFE<256OR(E>40960ANDE<49152)ORE>53247THENGOSUB
3000:GOTO230 : rem 183
250 IFE<STHENPRINTC$;"{RVS}ENDING < START
{2 SPACES }":GOSUB1000:GOTO 230 : rem 176
226
Appendix: D
260 PRINT: PRINT: PRINT : rem 179
300 PRINT" {CLR}" ;CHR$(14) :AD=S:P0KEV+21 ,0 : rem 225
310 A=l : PRINT RIGHT? ( "0000"+MID$ ( STR$ (AD) , 2) , 5) ; " : "
. : rem 33
315 F0RJ=AT06 s rem 33
320 GOSUB570:IFN=-1THENJ=J+N:GOTO320 :rem 228
390 IFN=-211THEN 710 : rem 62
400 IFN=-204THEN 790 srem 64
410 I FN=-206THENPRINT: INPUT "{DOWN} ENTER NEW ADDRES
S";ZZ srem 44
415 IFN=-206THENIFZZ<SORZZ>ETHENPRINT"{RVS}OUT OF
{SPACE}RANGE":GOSUB1000:GOTO410 : rem 225
417 IFN=-206THENAD=ZZ:PRINT:GOTO310 :rem 238
420 IF N<> —196 THEN 480 :rem 133
430 PRINT:INPUT"DISPLAY:FROM";F:PRINT, "TO"; :INPUTT
— :rem 234
440 I FF < SORF > EORT < SORT > ETHENP RI NT "AT LEAST " ; S ; "
{LEFT}, NOT MORE THAN";E:GOTO430 :rem 159
450 FORI=FTOTSTEP6 : PRINT : PRINTRIGHT$ ( "0000"+MID$ ( S
TR$(I),2),5);":"; :rem 30
451 FORK=0TO5 :N=PEEK ( I+K ) : PRINTRIGHT$ ( " 00 " +MID$ ( ST
R$(N),2),3) srem 66
460 GETA$:IFA$>*'"THENPRINT:PRINT:GOTO310 : rem 25
470 NEXTK:PRINTCHR$(20) ; :NEXTI:PRINT:PRINT:GOTO310
: rem 50
480 IFN<0 THEN PRINT:GOTO310 : rem 168
490 A(J)=N:NEXTJ srem 199
500 CKSUM=AD-INT ( AD/ 256 ) *256 : F0RI=1T06 : CKSUM= ( CKSU
M+A(I))AND255:NEXT srem 200
510 PRINTCHR$(18);:GOSUB570:PRINTCHR$(146);:rem 94
511 IFN=-1THENA=6:G0T0315 srem 254
515 PRINTCHR$(20) :IFN=CKSUMTHEN530 :rem 122
520 PRINT: PRINT "LINE ENTERED WRONG : RE-ENTER" :PRI
NT:GOSUB1000:GOTO310 ~ ~ srem 176
530 GOSUB2000 srem 218
540 F0RI=1T06:P0KEAD+I-1,A(I) :NEXT : POKE54272 , : POK
E54273,0 srem 227
550 AD=AD+6:IF AD<E THEN 310 srem 212
560 GOTO 710 srem 108
570 N=0:Z=0 srem 88
580 PRINT "g£3"; srem 81
581 GETA?:IFA$=""THEN581 srem 95
582 AV=-(A$="M" ) -2* (A$=" , " )-3* ( A$=" . " )-4* ( A$=" J" )-
5*(A$="K")-6*(A$="L" ) srem 41
583 AV=AV-7* (A$="U" ) -8* (A$="I " )-9* (A$="0" ) :IFA$="H
"THENA$="0" srem 134
584 IFAV>0THENA$=CHR$(48+AV) : rem 134
585 PRINTCHR$(20) ; :A=ASC(A$) :IFA=130RA=440RA=32THE
N 670 :rem 229
D: Appendix
590 I FA>128THENN=-A: RETURN : rem 137
600 IFA<>20 THEN 630 : rem 10
610 GOSUB690 : IFI=1ANDT=44THENN=-1 : PRINT" {OFF }
{LEFT} {LEFT}"; :GOTO690 : rem 62
620 GOTO570 : rem 109
630 IFA<48ORA>57THEN580 : rem 105
640 PRINTA$; :N=N*10+A-48 :rem 106
650 IFN>255 THEN A=20 :GOSUB1000 :GOTO600 :rem 229
660 Z=Z+1 :IFZ<3THEN580 : rem 71
670 IFZ=0THENGOSUB1000:GOTO570 : rem 114
680 PRINT", ";: RETURN : rem 240
690 S%=PEEK(209)+256*PEEK(210)+PEEK(211) : rem 149
691 FORI=lT03:T=PEEK(S%-I) : rem 67
695 IFT<>44ANDT<>58THENPOKES%-I,32:NEXT :rem 205
700 PRINTLEFT$("{3 LEFT} ", 1-1) ; : RETURN : rem 7
710 PRINT" {CLR} {RVS}*** SAVE ***{3 DOWN}" :rem 236
715 PRINT"{2 DOWN} (PRESS { RVS } RETURN { OFF } ( ALONE TO
CANCEL SAVE) {DOWN}" ~" : rem 106
720 F$="": INPUT" {DOWN} FILENAME" ;F$ : I FF$=" "THENPRI
NT: PRINT :GOTO310 : rem 71
>730 PRINT: PRINT" {2 DOWN} { RVS }T{ OFF }APE OR {RVS}D
{OFFjlSK: (T/D)" :rem 228
740 GETA$ : IFA$<> "T"ANDA$ <> "D"THEN740 : rem 36
750 DV=l-7* (A$="D" ) :IFDV=8THENF$="0: "+F$ :OPEN15,8,
15, "S"+F$:CLOSE15 :rem21.2
760 T$=F$ : ZK=PEEK ( 53 ) +256 *PEEK ( 54 ) -LEN ( T$ ) : POKE782
,ZK/256 :rem 3
762 POKE781 , ZK-PEEK ( 782 ) * 256 : POKE780 , LEN ( T$ ) : SYS65
469 :rem 109
763 POKE780,l:POKE781,DV:POKE782,l:SYS65466:rem 69
765 K=S:POKE254,K/256:POKE253,K-PEEK(254)*256:POKE
780,253 :rem 17
766 K=E+1 : POKE782 , K/256 : POKE781 , K-PEEK( 782 ) *256 : SY
S65496 :rem 235
770 IF(PEEK(783)AND1)OR(191ANDST)THEN780 : rem 111
775 PRINT " {DOWN} DONE. {DOWN}" :GOTO310 : rem 113
780 PRINT" {DOWN} ERROR ON SAVE. {2 SPACES }TRY AGAIN.
":IFDV=1THEN720 : rem 171
781 OPEN15,8,15:INPUT#15,El$,E2$:PRINTEl$;E2$:CLOS
E15:GOTO720 : rem 103
790 PRINT" {CLR} {RVS}*** LOAL ***{2 DOWN}" : rem 212
795 PRINT" {2 DOWN} (PRESS { RVS } RETURN { OFF } ^ALONE TO
CANCEL LOAD)" " : rem 82
800 F$="":INPUT"{2 DOWN} FILENAME" ;F$ :IFF$=" "THENP
RINT:GOTO310 " : rem 144
810 PRINT: PRINT" {2 DOWN} {RVS }T{ OFF} APE OR {RVS}D
{OFFjlSK: (T/D)" : rem 227
820 GETA$ : I FA$ <> " T " ANDA$ <> " D " THEN8 2 : rem 34
830 DV=1-7*(A$="D"):IFDV=8THENF$="0:"+F$ :rem 157
228
Appendix: D
840 T$=F$ : ZK=PEEK( 53 )+256*PEEK( 54) -LEN(T$ ) : POKE782
,ZK/256 srem 2
841 POKE781 , ZK-PEEK( 782 ) * 256 : POKE780 , LEN( T$ ) : SYS65
469 :rem 107
845 POKE780,l:POKE781,DV:POKE782,l:SYS65466:rem 70
850 POKE780,0:SYS65493 : rem 11
860 IF(PEEK(783)AND1)OR(191ANDST)THEN870 : rem 111
865 PRINT "{ DOWN }DONE. ":G0T03 10 : rem 96
•870 PRINT "{DOWN} ERROR ON LOAD. {2 SPACES } TRY AGAIN.
{DOWN} " :IFDV=1THEN800 srem 172
880 OPEN15,8,15:INPUT#15,El$,E2$:PRINTEl$;E2$sCLOS
E15:GOTO800 srem 102
1000 REM BUZZER srem 135
1001 POKE54296 , 15 :POKE54277 , 45 : POKE54278, 165
:rem 207
1002 POKE54276,33:POKE 54273 , 6 : POKE54272 , 5 : rem 42
1003 FORT=1TO200 :NEXT : POKE54276 , 32 : POKE54273 , sPOK
E54 272,0: RE TURN srem 202
2000 REM BELL SOUND srem 78
2001 POKE54296 , 15 : POKE54277 , : POKE54278 , 247
:rem 152
2002 POKE 54276, 17 :POKE54273 , 40 : POKE54272 , 0s rem 86
2003 FORT=lTO100sNEXT:POKE54276,16:RETURN srem 57
3000 PRINTC$;"{RVS}NOT ZERO PAGE OR ROM" :GOTO1000
:rem 89
E: Appendix
The 6502 Instruction Set
ADC Add Memory to Accumulator with Carry
Status Flags
N Z
• •
C I D
•
V
•
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Immediate
ADC #Arg
69
2
Zero Page
ADC Arg
65
2
Zero Page, X
ADC Arg, X
75
2
Absolute
ADC Arg
6D
3
Absolute, X
ADC Arg, X
7D
3
Absolute, Y
ADC Arg, Y
79
3
(Indirect, X)
ADC (Arg, X)
61
2
(Indirect), Y
ADC (Arg), Y
71
2
AND
AND Memory with Accumulator
Status Flags
N Z
• •
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Immediate
AND #Arg
29
2
Zero Page
AND Arg
25
2
Zero Page, X
AND Arg, X
35
2
Absolute
AND Arg
2D
3
Absolute, X
AND Arg, X
3D
3
Absolute, Y
AND Arg, Y
39
3
(Indirect, X)
AND (Arg, X)
21
2
(Indirect), Y
AND (Arg), Y
31
2
230
Appendix: E
ASL
Shift Left One Bit
Status Flags
N Z
C I
E
» V
• •
•
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Accumulator
ASL A
OA
1
Zero Page
ASL Arg
06
2
Zero Page, X
ASL Arg, X
16
2
Absolute
ASL Arg
OE
3
Absolute, X
ASL Arg, X
IE
3
BCC
Branch on Carry Clear
Status Flags
N Z
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Relative
BCC Arg
90
2
BCS
Branch on Carry Set
Status Flags
N Z
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Relative
BCS Arg
BO
2
BEQ
Branch on Zero
Status Flags
N Z
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Relative
BEQ Arg
F0
2
E: Appendix
BIT Test Bits in Memory Against Accumulator
Status Flags
N Z
• •
C I D V
•
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Zero Page
BIT Arg
24
2
Absolute
BIT Arg
2C
3
BMI
Branch on Minus
Status Flags
N Z
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Relative
BMI Arg
30
2
BNE
Branch on Anything but Zero
Status Flags
N Z
C I D
. V
Addressing
Mode
Mnemonics
Opcode
Size
In Bytes
Relative
BNE Arg
DO
2
BPL
Branch on Plus
Status Flags
N Z
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Relative
BPL Arg
10
2
232
Appendix: E
BRK
Break
Status Flags
N Z
C I D
•
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
BRK
00
1
BVC
Branch on Overflow Clear
Status Flags
N Z
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Relative
BVCArg
50
2
BVS
Branch on Overflow Set
Status Flags
N Z
C I D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Relative
BVSArg
70
2
CLC
Clear Carry Flag
Status Flags
N Z
C I D
•
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
CLC
18
1
E: Appendix
CLD
Clear Decimal Mode
Status Flags
N Z
C I
D V
#
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
CLD
D8
1
CLI
Clear Interrupt Disable Bit
Status Flags
N Z
C I
•
D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
CLI
58
1
CLV
Clear Overflow Flag
Status Flags
N Z
C I
D
V
•
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
CLV
B8
1
CMP
Compare Memory and Accumulator
Status Flags
N Z
• •
C I
•
D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Immediate
Zero Page
Zero Page, X
Absolute
Absolute, X
Absolute, Y
(Indirect, X)
(Indirect), Y
CMP #Arg
CMP Arg
CMP Arg, X
CMPAtg
CMP Arg, X
CMP Arg, Y
CMP (Arg, X)
CMP (Arg), Y
C9
C5
D5
CD
DD
D9
CI
Dl
2
2
2
3
3
3
2
2
234
n
1
Appendix: E
I 1
n
CPX
Compare Memory Against X Register
n
Status Flags
N Z
• •
C I D
•
V
n
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Immediate
Zero Page
Absolute
CPX #Arg
CPXArg
CPXArg
EO
E4
EC
2
2
3
CPY Compare Memory Against Y Register
Status Flags
N Z
C I D
V
• •
•
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Immediate
CPY #Arg
CO
2
Zero Page
CPYArg
C4
2
Absolute
CPYArg
cc
3
DEC
Decrement Memory by One
Status Flags
N Z
• •
C I D V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Zero Page
DEC Arg
C6
2
Zero Page, X
DEC Arg, X
D6
2
Absolute
DEC Arg
CE
3
Absolute, X
DEC Arg, X
DE
3
DEX
Decrement X Register by One
Status Flags
N Z
• •
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
DEX
CA
1
235
E: Appendix
DEY
Decrement Y Register by One
Status Flags
N Z
• •
C I E
» V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
DEY
88
1
EOR Exclusive-OR Memory with Accumulator
Status Flags
N Z
• •
C I E
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Immediate
EOR #Arg
49
2
Zero Page
EOR Arg
45
2
Zero Page, X
EOR Arg, X
55
2
Absolute
EOR Arg
4D
3
Absolute, X
EOR Arg, X
5D
3
Absolute, Y
EOR Arg, Y
59
3
(Indirect, X)
EOR (Arg, X)
41
2
(Indirect), Y
EOR (Arg), Y
51
2
INC
Increment Memory by One
Status Flags
N Z
• •
C I
I
)
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Zero Page
Zero Page, X
Absolute
Absolute, X
INC Arg
INC Arg, X
INC Arg
INC Arg, X
E6
F6
EE
FE
2
2
3
3
Appendix: E
INX
Increment X Register by One
Status Flags
N Z
• •
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
INX
E8
1
INY
Increment Y Register by One
Status Flags
N Z
• •
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
INY
C8
1
JMP
Jump
Status Flags
N Z
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Absolute
JMP Arg
4C
3
Indirect
JMP(Arg)
6C
3
JSR Jump to New Location, but Save Return Address
Status Flags
N Z
C I D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Absolute
JSR Arg
20
3
237
u
E: Appendix
LDA
Load Accumulator with Memory
Statue Flnoc
N Z
• •
C I D
V
Addressing
Mnemonics
Opcode
Size
nuuc
in Bytes
Immediate
LDA #Arg
A9
2
Zero Page
LDA Arg
A5
2
Zero Page, X
LDA Arg, X
B5
2
Absolute
LDA Arg
AD
3
Absolute, X
LDA Arg, X
BD
3
Absolute, Y
LDA Arg, Y
B9
3
(Indirect, X)
LDA (Arg, X)
Al
2
(Indirect), Y
LDA (Arg), Y
Bl
2
LDX
Load X Register
Status Flags
N Z
• •
C I E
> V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Immediate
LDX #Arg
A2
2
Zero Page
LDX Arg
A6
2
Zero Page, Y
LDX Arg, Y
B6
2
Absolute
LDX Arg
AE
3
Absolute, Y
LDX Arg, Y
BE
3
LDY
Load Y Register
Status Flags
N Z
• •
C I E
> V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Immediate
LDY #Arg
AO
2
Zero Page
LDY Arg
A4
2
Zero Page, X
LDY Arg, X
B4
2
Absolute
LDY Arg
AC
3
Absolute, X
LDY Arg, X
BC
3
u
238
U
! 1
I — | Appendix: E
I I
n
LSR Shift Right One Bit in Either Memory or Accumulator
Status Flags
N Z
• •
C I
•
I
)
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Accumulator
LSR A
4A
1
Zero Page
LSR Arg
46
2
Zero Page, X
LSR Arg, X
56
2
Absolute
LSR Arg
4E
3
Absolute, X
LSR Arg, X
5E
3
NOP
No Operation
Status Flags
N Z
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
NOP
EA
1
ORA
OR Memory with Accumulator
Status Flags
N Z
• •
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Immediate
ORA #Arg
09
2
Zero Page
ORA Arg
05
2
Zero Page, X
ORA Arg, X
15
2
Absolute
ORA Arg
0D
3
Absolute, X
ORA Arg, X
ID
3
Absolute, Y
ORA Arg, Y
19
3
(Indirect, X)
ORA (Arg, X)
01
2
(Indirect), Y
ORA (Arg), Y
11
2
239
E: Appendix
PHA
Push Accumulator onto the Stack
Status Flags
N Z
C I D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
PHA
48
1
PHP
Push Processor Status onto the Stack
Status Flags
N Z
C I D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
PHP
08
1
PLA
Pull Accumulator from the Stack
Status Flags
N Z
• •
C I D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
PLA
68
1
PLP
Pull Processor Status from the Stack
Status Flags
N Z C I D
From Stack
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
PLP
28
1
240
Appendix: E
ROL Rotate One Bit Left in Memory or the Accumulator
Status Flags
N Z
C I
D
V
• •
•
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Accumulator
ROL A
2A
1
Zero Page
ROL Arg
26
2
Zero Page, X
ROL Arg, X
36
2
Absolute
ROL Arg
2E
3
Absolute, X
ROL Arg, X
3E
3
ROR Rotate One Bit Right in Memory or the Accumulator
Status Flags
N Z
C I E
t
V
• •
•
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Accumulator
ROR A
6A
1
Zero Page
ROR Arg
66
2
Zero Page, X
ROR Arg, X
76
2
Absolute
ROR Arg
6E
3
Absolute, X
ROR Arg, X
7E
3
RTI
Return from Interrupt
Status Flags
N Z C I D
From Stack
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
RTI
40
1
241
E: Appendix
RTS
Return front Subroutine
Status Flags
N Z
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
RTS
60
1
SBC Subtract Memory from Accumulator, with Borrow
Status Flags
N Z
C I E
V
• •
•
•
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Immediate
SBC #Arg
E9
2
Zero Page
SBC Arg
E5
2
Zero Page, X
SBC Arg, X
F5
2
Absolute
SBC Arg
ED
3
Absolute, X
SBC Arg, X
FD
3
Absolute, Y
SBC Arg, Y
F9
3
(Indirect, X)
SBC (Arg, X)
El
2
(Indirect), Y
SBC (Arg), Y
Fl
2
SEC
Set Carry Flag
Status Flags
N Z
C I D
•
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
SEC
38
1
242
Appendix: E
SED
Set Decimal Mode
Status Flags
N Z
C I
D
•
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
SED
F8
1
SEI
Set Interrupt Disable Status
Status Flags
N Z
C I
•
D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
SEI
78
1
STA
Store Accumulator in Memory
Status Flags
N Z
C I
D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Zero Page
Zero Page, X
Absolute
Absolute, X
Absolute, Y
(Indirect, X)
(Indirect), Y
STAArg
STA Arg, X
STAArg
STA Arg, X
STA Arg, Y
STA (Arg, X)
STA (Arg), Y
85
95
8D
9D
99
81
91
2
2
3
3
3
2
2
243
E: Appendix
STX
Store X Register in Memory
Status Flags
N Z
C I
E
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Zero Page
Zero Page, Y
Absolute
STXArg
STX Arg, Y
STXArg
86
96
8E
2
2
3
STY
Store Y Register in Memory
Status Flags
N Z
C I
D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Zero Page
Zero Page, X
Absolute
STY Arg
STY Arg, X
STY Arg
84
94
8C
2
2
3
TAX
Transfer Accumulator to X Register
Status Flags
N Z
• •
C I
D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
TAX
AA
1
TAY
Transfer Accumulator to Y Register
Status Flags
N Z
• •
C I
D
V
Addressing
Mode
Mnemonics
Opcode
Size
in Bytes
Implied
TAY
A8
1
244
Appendix: E
TSX
Transfer Stack Pointer to X Register
Status Flags
N Z
• •
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
TSX
BA
1
TXA
Transfer X Register to Accumulator
Status Flags
N Z
• •
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
TXA
8A
1
TXS
Transfer X Register to Stack Pointer
Status Flags
N Z
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
TXS
9A
1
TYA
Transfer Y Register to Accumulator
Status Flags
N Z
• •
C I D
V
Addressing
Mnemonics
Opcode
Size
Mode
in Bytes
Implied
TYA
98
1
245
F: Appendix
Number Tables
This lookup table should make it convenient when you need to
translate hex, binary, or decimal numbers. The first column lists the
decimal numbers between 1 and 255. The second column is the
hexadecimal equivalent. The third column is the decimal equivalent
of a hex most significant byte, or MSB. The fourth column is
the binary.
If you need to find out the decimal equivalent of the hex number
$FD15, look up $FD in the Hex column and you'll see that it's 64768.
Then look up the $15 in the Hex column (it's 21 decimal) and add
21 + 64768 to get the answer: 64789-
Going the other way, from decimal to hex, you could translate
64780 into hex by looking in the MSB column for the closest number
(it must be smaller, however). In this case, the closest smaller number
is 64768 so jot down JSFD as the hex MSB. Then subtract 64768 from
64780 to get the LSB: 12. Look up 12 in the decimal column (it is
$0C hex) and put the $¥D MSB together with the $0C LSB for your
answer: $FD0C.
With a little practice, you can use this chart for fairly quick
conversions between the number systems. Most of your translations
will only involve going from hex to decimal or vice versa with the
LSB of hex numbers, the first 255 numbers, which require no addition
or subtraction. Just look them up in the table.
Hex
LSB
MSB
Biliary
01
1
256
00000001
02
2
512
00000010
03
3
768
00000011
04
4
1024
00000100
05
5
1280
00000101
06
6
1536
00000110
07
7
1792
00000111
08
8
2048
00001000
09
9
2304
00001001
OA
10
2560
00001010
246
n
n
i !
H
n
Appendix: F
n
Hex
LSB
MSB
Binary
OB
11
2816
00001011
OC
12
3072
00001100
OD
13
3328
00001101
OE
14
3584
00001110
OF
15
3840
00001111
10
16
4096
00010000
1 1
17
4352
00010001
12
18
4608
00010010
13
19
4864
00010011
14
20
5120
00010100
15
21
5376
00010101
16
22
5632
00010110
17
23
5888
00010111
18
24
6144
00011000
19
25
6400
00011001
1A
26
6656
00011010
IB
27
6912
00011011
1C
28
7168
00011100
ID
29
7424
00011101
IE
30
7680
00011110
IF
31
7936
00011111
20
32
8192
00100000
2 1
33
8448
00100001
22
34
8704
00100010
23
35
8960
00100011
24
36
9216
00100100
25
37
9472
00100101
26
38
9728
00100110
27
39
9984
00100111
28
40
10240
00101000
29
41
10496
00101001
2A
42
10752
00101010
2B
43
11008
00101011
2C
44
1 1264
00101100
2D
45
11520
00101101
2E
46
11776
00101110
2F
47
12032
00101111
30
48
12288
00110000
31
49
12544
00110001
32
50
12800
001 10010
33
51
13056
001 1001 1
34
52
13312
001 10100
35
53
13568
00110101
36
54
13824
00110110
37
55
14080
00110111
38
56
14336
001 11000
39
57
14592
00111001
3A
58
14848
00111010
3B
59
15104
00111011
3C
60
15360
00111100
3D
61
15616
00111101
3E
62
15872
00111110
247
F: Appendix
Hex
LSB
MSB
Binary
3F
63
16128
00111111
40
64
16384
01000000
4 1
65
16640
01000001
42
66
16896
01000010
43
67
17152
01000011
44
68
17408
01000100
45
69
17664
01000101
46
70
17920
01000110
47
71
18176
010001 1 1
48
72
18432
01001000
49
73
18688
01001001
4A
74
18944
01001010
4B
75
19200
01001011
4C
76
19456
01001100
4D
77
19712
01001101
4E
78
19968
01001110
4 F
79
20224
01001111
50
80
20480
01010000
5 1
81
20736
01010001
52
82
20992
01010010
53
83
21248
01010011
54
84
21504
01010100
55
85
21760
01010101
56
86
22016
01010110
57
87
22272
01010111
58
88
22528
01011000
59
89
22784
0101 1001
5A
90
23040
01011010
5B
91
23296
01011011
5C
92
23552
01011100
5D
93
23808
01011101
5E
94
24064
01011110
5F
95
24320
01011111
60
96
24576
1 1 00000
6 1
97
24832
01 100001
62
98
25088
01100010
63
99
25344
01100011
64
100
25600
01100100
65
101
25856
01100101
66
102
26112
01 1001 10
67
103
26368
01 1001 1 1
68
104
26624
01101000
69
105
26880
01101001
6A
106
27136
01101010
6B
107
27392
01101011
6C
108
27648
01101100
6D
109
27904
01101101
6E
110
28160
01101110
6F
111
28416
01101111
70
112
28672
01110000
71
113
28928
01110001
72
114
29184
01110010
u
u
□
□
u
248
u
u
u
□
u
n
n
n
n
n
n
n
Appendix: F
Hex
LSB
MSB
Binary
73
115
29440
01110011
74
116
29696
01110100
75
117
29952
01110101
76
118
30208
01110110
77
119
30464
01110111
78
120
30720
01111000
79
121
30976
01111001
7A
122
31232
01111010
7B
123
31488
01111011
7C
124
31744
01111100
7D
125
32000
01111101
7E
126
32256
01111110
7F
127
32512
01111111
80
128
32768
10000000
81
129
33024
10000001
82
130
33280
10000010
83
131
33536
10000011
84
132
33792
10000100
85
133
34048
10000101
86
134
34304
10000110
87
135
34560
10000111
88
136
34816
10001000
89
137
35072
10001001
8A
138
35328
10001010
8B
139
35584
10001011
8C
140
35840
10001100
8D
141
36096
10001101
8E
142
36352
10001110
8F
143
36608
10001111
90
144
36864
10010000
91
145
37120
10010001
92
146
37376
10010010
93
147
37632
10010011
94
148
37888
10010100
95
149
38144
10010101
96
150
38400
10010110
97
151
38656
10010111
98
152
38912
10011000
99
153
39168
10011001
9 A
154
39424
10011010
9B
155
39680
10011011
9C
156
39936
10011100
9D
157
40192
10011101
9E
158
40448
10011110
9F
159
40704
10011111
AO
160
40960
10100000
Al
161
41216
10100001
A2
162
41472
10100010
A3
163
41728
10100011
A4
164
41984
10100100
A5
165
42240
10100101
A6
166
42496
10100110
249
F: Appendix
Hex
LSB
MSB
Binary
A7
167
42752
1 1 00 1 1 1
A8
168
43008
10101 000
A9
169
43264
10101001
AA
170
43520
10101010
AB
171
43776
IOIOIOI l
AC
172
44032
1 1 1 1 00
AD
173
44288
10101 101
AE
174
A As A A
44544
10101 1 10
AF
175
44800
10101 111
BO
176
45056
101 10000
B 1
177
453 12
1011 000 1
B2
178
45568
1 1 1 00 1
B3
179
45824
101 1001 1
D A
B4
180
46080
1 1 1 1 00
B5
181
A /" 1 1 f
46336
101 10101
Bo
182
46592
10110110
B7
183
46848
101 101 1 1
B8
184
47104
10111 000
B9
185
47360
1 1 1 1 00 1
BA
186
47616
IOI l ioio
BB
187
47872
10111011
BC
188
48128
101 1 1 100
BD
189
48384
101 1 1101
BE
190
48640
101 11110
B F
191
48896
10111111
CO
192
49152
I l 000000
C 1
193
A r\ A rvo
49408
1 1000001
C2
194
A(\f Y A
49oo4
11000010
C3
195
49920
1 1 0000 1 1
C4
196
50176
1 1000100
C5
197
50432
1 1000101
C6
198
50688
1 10001 10
C7
199
50944
1 10001 1 1
C8
200
51200
1 1001000
C9
201
51456
1 1001001
CA
202
51712
1 1001010
CB
203
51968
1 100101 1
CC
204
52224
1 1001 100
CD
205
52480
1 1 00 1 1 1
CE
206
52736
11 001 1 10
C F
207
52992
1 1001 111
DO
one
53^48
1 1 A 1 AAAA
1 1 u 1 uooo
Dl
209
53504
11010001
D2
210
53760
11010010
D3
211
54016
11010011
D4
212
54272
11010100
D5
213
54528
11010101
D6
214
54784
11010110
D7
215
55040
11010111
D8
216
55296
11011000
D9
217
55552
11011001
DA
218
55808
11011010
u
u
u
u
u
250
u
u
u
u
u
Appendix: F
Hex
t cn
DB
219
56064
l I0l lull
DC
220
56320
l IOI l 100
DD
221
56576
l IOI l IOI
DE
222
56832
l lOll l 10
DF
223
57088
i ioi mi
EO
224
57344
111 AAA/\A
111 00000
E 1
225
57600
1 1 100001
E2
226
57856
1 1 100010
E3
227
581 12
1 1 10001 1
E4
228
58368
111 f\f\ 1 t\t\
1 1 100100
E5
229
58624
1 1 100101
E6
230
58880
1 1 1001 10
E7
231
59136
11100111
E8
232
59392
11101000
E9
233
59648
1 1 101001
EA
234
59904
11101010
E6
235
60160
11101011
EC
236
60416
11101100
ED
237
60672
11101101
EE
238
60928
11101110
EF
239
61 184
1 1 101 111
FO
240
61440
11110000
F 1
241
61696
111 10001
F2
242
61952
11110010
F3
243
62208
11110011
F4
244
/'I AS A
62464
1111 f\ -| r\f\
1 1 1 10100
F5
-\A £
245
OZl Z\J
1 1 1 mini
F6
246
62976
11110110
F7
247
63232
11110111
F8
248
63488
11111000
F9
249
63744
11111001
FA
250
64000
11111010
FB
251
64256
11111011
FC
252
645 12
11111100
FD
253
64768
11111101
FE
254
65024
11111110
FF
255
65280
11111111
The following program will print copies of this number table. You might need to
make some adjustments to the printout conventions and your printer itself.
Table Printer
For mistake-proof program entry, be sure to read "The Automatic Proofreader," Appendix C.
10 OPEN4,4:REM OPEN CHANNEL TO PRINTER : rem 55
100 HE$="0123456789ABCDEF" :rem 101
110 FOR X=l TO 255:D=X:GOSUB 230 :rem 224
120 L$=RIGHT$("{4 SPACES } " +STR$ ( X ) , 6 ) : rem 202
130 M$=RIGHT$("{4 SPACES } "+STR$ (X*256 ) ,8) :rem 149
251
F: Appendix
140 PRINT#4,H$;L$;M$;"{3 SPACES}"; :rem 34
145 REM CREATE BINARY jrem 247
150 C=1:B=2:IF X AND 1 THEN B$ (C)«"l" :GOTO 170
:rem 61
160 B$(C)="0" :rem 66
170 C=C+1:IF B AND X THEN B$ (C)= M 1" :GOTO 190
:rem 213
180 B$(C)="0" :rem 68
190 B=B*2:IFC>8 THEN 210 :rem 251
200 GOTO 170 :rem 99
210 FOR 1=8 TO 1 STEP— 1 :PRINT#4 , B$ ( I ) ; :NEXT I
srem 237
220 PRINT#4 : NEXTX : END :rem 90
225 REM CONVERT TO HEX :rem 38
230 H$="" :FOR M=l TO STEP-1 :N%=D/( 16fM) :D=D-N%*1
6tM :rem 102
240 H$=H$+MID$ (HE$ /N%+1 , 1 ) : NEXT: RETURN :rem 193
252
n
n
R
' i
Index
n
n
n
n
rs
i i
n
n
accumulator 23
ADC (ADd memory to accumulator with
Carry) instruction 230
address 8
addressing modes 8
"A Disassembler" program 14-19
AND (AND memory with accumulator)
instruction 230
animation 135
arcade games 4
"Area-Fill Routine" (Graphics Package)
154-55, 160-61
arrays, how stored 102
ASCII code 91, 186
ASCII files 204-5
"ASCII/POKE Printer" program 91-95
ASL (Shift Left one bit) instruction 231
assembler 5, 6-9, 14, 98
"Assembler, The" program 6-13
AUTO command (BASIC Aid) 46
"Auto Line Numbering" "program 69-70
"Automatic Proofreader" 219-22
BASIC v, 3, 14
"BASIC Aid" program v, 45-67
"BASIC Maze Generator" program 181
BCC (Branch on Carry Clear) instruction
231
BCS (Branch on Carry Set) instruction
231
BEQ (Branch if EQual) instruction 15, 231
BIT (test BITs in memory against accu-
mulator) instruction 232
bitmapped graphics 26-30
BMI (Branch on Minus) instruction 232
BNE (Branch if Not Equal to zero)
instruction 24, 232
BPL (Branch on PLus) instruction 232
BREAK command (in "BASIC Aid"
program) 47
BRK (BReaK) instruction 6, 233
BVC (Branch on oVerflow Clear) instruc-
tion 233
BVS (Branch on oVerflow Set) instruction
233
byte 6
cassette buffer 76, 89, 91-92, 191, 205,
209
CHANGE command (in "BASIC Aid"
program) 47-48
character sets, editing 111-18
CHRGET ROM routine 81
CHROUT ROM routine 93
CLC (CLear Carry flag) instruction 233
CLD (CLear Decimal mode) instruction
234
CLI (CLear Interrupt disable bit) instruc-
tion 234
CLV (CLear oVerflow flag) instruction
234
CMP (CoMPare memory and accu-
mulator) instruction 234
Cochrane, F. Arthur 45
COLD command (in "BASIC Aid" pro-
gram) 48
Commodore 64 Programmer's Reference
Guide 72, 92
COMPUTE'S First Book of 64 Sound and
Graphics 115,151
COMPUTEl's Reference Guide to Com-
modore 64 Graphics 115, 151
COMPUTE'S Second Book of Machine
Language 5
CPX (ComPare memory against
x register) instruction 235
CPY (ComPare memory against
y register) instruction 235
CRT command (in "BASIC Aid" pro-
gram) 48
cursor control 78-79
"DATAmaker" program 24-25
DATA statement 117, 137-38, 215
DEC (DECrement memory by one)
instruction 235
DELETE command (in "BASIC Aid" pro-
gram) 48-49
"Demo/scan" program 188
DEX (DEcrement x register by one)
instruction 235
DEY (DEcrement y register by one)
instruction 236
"Disassembler" program 23
disassembling 14-19
"Disk Defaulter" program 106-7
DOS support commands (in "BASIC
Aid" program) 52-53
"Dr. Video" program 78-79
DUMP command (in "BASIC Aid"
program) 49
EOR (Exclusive-OR memory with accu-
mulator) instruction 236
FIND command (in "BASIC Aid"
program) 49
FLIST command (in "BASIC Aid"
program) 49
"Foolproof Input" program 83-86
"Four-Speed Brake" program 89-90
253
function keys 74-75, 89-90
GET statement 84
GETIN ROM routine 93
HELP command (in "BASIC Aid" pro-
gram) 49-50
HEX command (in "BASIC Aid" pro-
gram) 50
Hoare, C.A.R. 196
immediate addressing 8
implied addressing 8
INC (INCrement memory by one)
instruction 236
INPUT statement 83-85
interrupts 78
inverse video 92
INX (INcrement X) instruction 7, 24, 237
INY (INcrement Y) instruction 237
IRQ (Interrupt ReQuest) 78-79, 98-99
JMP (JuMP) instruction 6, 191, 237
joystick 112, 132-33, 167-68
JSR (Jump to SubRoutine) instruction 6,
191, 237
Kemal ROM 29, 71
"Keyscan" program 187-88
KILL command (in "BASIC Aid" pro-
gram) 50
LDA (LoaD the Accumulator) instruction
14, 23, 238
LDX (LoaD X) instruction 23, 238
LDY (LoaD Y) instruction 7, 238
"Line-Draw Routine" 154, 158-60
LIST command 14-15
listing conventions 217-18
LSR instruction 239
"Machine Language Maze Generator"
program 181-84
maze generator programs 178-85
algorithm 178-80
flow chart 185
memory locations, safe 91
MERGE command (in "BASIC Aid"
program) 50
mixing BASIC and ML 4-5
"MLX" program 45-46, 111, 132, 223-29
mnemonics 5, 6-8
"Monitor Disassembly" program 22-23
multicolor mode 115-16, 153-56
NOP (No OPeration) instruction 239
number tables 246-51
"Numeric Keypad" program 71-73
colors and 72
OFF command (in "BASIC Aid" pro-
gram) 50-51
OLD command (in "BASIC Aid" pro-
gram) 50
"One-Touch Commands" program 74-77
254
ORA (OR memory with Accumulator)
instruction 239
"Package Demonstration" program
162-64
pages, memory 22
PHA (PusH Accumulator onto stack)
instruction 240
PHP (PusH Processor status onto stack)
instruction 240
PLA (PuLl Accumulator from stack)
instruction 240
"Plotstring" programs 26-41
PLP (PuLl Processor status from stack)
instruction 240
"Point-Plot Routine" 152-54, 157-58
pointers, BASIC 103-4
PRINT command 91
"Quick Clear" routines 3-4
Quicksort algorithm 196
quote mode 97-100
"RAMtest" program 209-11
READ command (in "BASIC Aid"
program) 51
RENUMBER command (in "BASIC Aid"
program) 51
REPEAT command (in "BASIC Aid"
program) 51
ROL (ROtate one bit Left in memory or
the accumulator) instruction 241
ROM character addresses 42
ROR (ROtate one bit Right in memory or
the accumulator) instruction 241
RTI (ReTurn from Interrupt) instruction
241
RTS (ReTurn from Subroutine) instruc-
tion 6, 242
SBC (SuBtract memory from accumulator
with borrow) 242
SCROLL command (in "BASIC Aid"
program) 51-52
"Scroll 64" program 171-75
scrolling 171-74
SEC (SEt Carry flag) instruction 242
SED (SEt Decimal mode) instruction 243
SEI (SEt Interrupt disable status) instruc-
tion 243
shell sort 196
6502 instruction set 230-45
6510 chip 3, 132
"64 Escape Key" program 97-101
"64 Freeze" program 202-3
"64 Loader" program 21-22
"64 Merge" program 204-8
"64 Paddle Reader" program 176-77
"64 Searcher" program 87-88
"Sort Test" program 201
\
"Sprite Magic" sprite editor 131-49
sprite page number 134
sprite seam 167
sprites 131-39
multicolor 135-37
BASIC and 167
STA (STore the Accumulator) instruction
24, 210, 243
START command (in "BASIC Aid"
program) 52
"Step Lister" program 80-82
Strasma, James 45
"String Search" program 191-95
STX (STore x register in memory) instruc-
tion 244
STY (STore Y) instruction 7, 244
"Table Printer" program 251-52
TAX (TrAnsfer accumulator to x register)
instruction 244
TAY (Transfer Accumulator to y register)
instruction 244
"Timed Search" program 195
tokens, BASIC 14, 80-81
TSX (Transfer Stack pointer to x register)
instruction 245
"Two-Sprite' Joystick" program 167-70
TXA (Transfer x register to Accumulator)
instruction 245
TXS (Transfer x register to Stack pointer)
instruction 245
TYA (Transfer y register to Accumulator)
instruction 245
"Ultrafont + Character Editor" program
111-30, 131
"Ultrasort" program 196-201
"Variable Lister" program 102-5
variables, where stored 102
wedges 80-81
windowing 171-72
"Window, The" program 22
word processors 4
x register 23
y register 8
zero page 191-92
255
□
□
□
□
□
D
□
COMPUTE! Books
P.O. Box 5406 Greensboro, NC 27403
Ask your retailer for these COMPUTE! Books. If he or she
has sold out, order directly from COMPUTE!
For Fastest Service
Call Our TOLL FREE US Order Line
800-334-0868
In NC call 919-275-9809
Quantity Title Price Total
Machine Language for Beginners $14.95*
Home Energy Applications $14.95*
COMPUTED First Book of VIC $12.95*
COMPUTED Second Book of VIC $12.95*
COMPUTED First Book of VIC Games $12.95*
COMPUTED First Book of 64 $12.95*
COMPUTEI's First Book of Atari $12.95*
COMPUTEI's Second Book of Atari $12.95*
COMPUTEI's First Book of Atari Graphics $12.95*
COMPUTEI's First Book of Atari Games $12.95*
Mapping The Atari $14.95*
Inside Atari DOS $19.95*
The Atari BASIC Sourcebook $12.95*
Programmer's Reference Guide for TI-99/4A $14.95*
COMPUTEI's First Book of Tl Games $12.95*
Every Kid's First Book of Robots and Computers $ 4.95T
The Beginner's Guide to Buying A Personal
Computer $ 3.95t
■ Add $2 shipping and handling. Outside US add $5 air mail: $2
surface mail.
tlAdd $1 shipping and handling. Outside US add $5 air mail; $2
surface mail
Please add shipping and handling for each book
ordered.
Total enclosed or to be charged.
All orders must be prepaid (money order, check, or charge). All
payments must be in US funds. NC residents add 4% sales tax.
□ Payment enclosed Please charge my: □VISA □MasterCard
□ American Express Acc't. No. Expires /
Name ___
Address
City State Zip.
Country
Allow 4-5 weeks for delivery.
□
□
□
□
□
D
□
If you've enjoyed the articles in this book, you'll find the
same style and quality in every monthly issue of COMPUTE!
Magazine. Use this form to order your subscription to
COMPUTE!.
For Fastest Service,
Call Our Toll-Free US Order Line
800-334-0868
In NC call 919-275-9809
COMPUTE!
P O Box 5406
Greensboro. NC 27403
My Computer Is:
□ Commodore 64 □ TI-99/4A □ Timex/Sinclair □VIC-20 □ PET
□ Radio Shack Color Computer □ Apple □ Atari □ Other
□ Don't yet have one...
□ $24 One Year US Subscription
□ $45 Two Year US Subscription
□ $65 Three Year US Subscription
Subscription rates outside the US:
□ $30 Canada
□ $42 Europe, Australia, New Zealand/Air Delivery
□ $52 Middle East, North Africa, Central America/Air Mail
□ $72 Elsewhere/Air Mail
□ $30 International Surface Mail (lengthy, unreliable delivery)
Name
Address
City State Zip
Country
Payment must be in US Funds drawn on a US Bank; International Money
Order, or charge card.
□ Payment Enclosed □ VISA
□ MasterCard □ American Express
Acc t. No. Expires /
□
□
□
□
□
D
□
If you've enjoyed the articles in this book, you'll find
the same style and quality in every monthly issue of
COMPUTERS Gazette for Commodore.
For Fastest Service
Call Our Toil-Free US Order Line
800-334-0868
In NC call 919-275-9809
COMPUTED WMMWWWm
P.O. Box 5406
Greensboro, NC 27403
My computer is:
□ Commodore 64 □VIC-20 □ Other
01 02 03
□ $20 One Year US Subscription
□ $36 Two Year US Subscription
□ $54 Three Year US Subscription
Subscription rates outside the US:
□ $25 Canada
□ $45 Air Mail Delivery
□ $25 International Surface Mail
Name
Address
City State Zip
Country
Payment must be in US Funds drawn on a US Bank, International Money
Order, or charge card. Your subscription will begin with the next avail-
able issue. Please allow 4-6 weeks for delivery of first issue. Subscription
prices subject to change at any time.
□ Payment Enclosed □ VISA
□ MasterCard □ American Express
Acct. No. Expires I
The COMPUTEts Gazette subscriber list Is made available to carefully screened organiza-
tions with a product or service which may be of Interest to our readers. If you prefer not to
receive such mailings, please check this box □ .
□
□
□
□
□
D
□
D
□
□
D
□
D
□
□
□
n
Speed and Power
Machine language, the language that your Commodore 64 uses
to calculate and process information, is fast and powerful. Much
more so than BASIC, the programming language you're probably
most familiar with. Until now, unless you knew how to program
in ML, you could only look at machine language programs with
envy. But it is possible to make BASIC and machine language
work together.
The routines and programs in this book can be easily added to
your own BASIC programs, or simply placed in your computer's
memory. Once in your program or in the 64's memory, they can c|0
make it easier to program, create dazzling, high-speed graphics,
speed up games, merge files, or sort thousands of items. All you m 3
have to do is type them in. ■ 40
The best machine language programs from recent issues of COM- 1 1
PUTE! magazine and COMPUTED Gazette have been revised and -+ ^
enhanced for this book. Other programs appear here for the first ^ >
time anywhere. And all are of the high quality you expect from H
COMPUTE! Publications. Q ~
Here are some of the routines and programs you'll find in this 3 S
book: 3 _
• "BASIC Aid," which gives you 20 tools to make BASIC Q §
programming easier. (Q
• Routines which automatically number BASIC program (j) ^
lines, turn your keyboard into a numeric keypad, and let q^q
you enter BASIC commands with one key. (D
• High-speed graphics applications, such as "Ultrafont +,"
"Sprite Magic," and "The Graphics Package."
• Arcade-speed joystick, paddle, and keyboard controllers. COWUTf
• Programs that let you search for specific strings, sort
lists, freeze the screen, merge files, or even test your 64's
RAM chip.
• A machine language assembler, a disassembler, and sim-
ple explanations of how ML is created and how it works.
You'll find these routines and their detailed explanations easy to
use, right from the moment you finish typing them in. There are
even programs included to insure error-free entry of every pro-
gram. With this book, and your own BASIC programs, you'll
soon be using the power and speed of ML.
ISBN 0-942386-48-5